java高并发

来源:互联网 发布:网络远程教育在哪报名 编辑:程序博客网 时间:2024/06/14 14:44

 找工作的时候是否经常看到要求有高并发,分布式系统的开发设计经验,或者高并发,分布式系统的开发设计经验者优先等字样,这时候情不自禁的搜索一下什 么是并发,多少算高并发,再思索一下自己的经历哪些是符合这个要求的?那么什么是并发,开发中的并发是怎么处理的,简单了解一下吧。

        在介绍并发之前我们先了解一下串行和并行:

        热闹的景点,买票人很多,这时只有一个窗口售票,大家排队依次买票就可以理解为串行。

        排队人太多了,旁边又加开了几个窗口,多人在不同的窗口同时买票可以理解为并行。

        如果只能开一个窗口,这时好多着急的人围上来,有问价格的,有掏钱的,又有取票的,在这个过程中售票员在同时应对多个买票人,可以理解为并发。

        我们经常在计算机上一边听歌一边写文档(或者处理其他的事情),这就是一种并发行为,表面看两个程序是同时进行,为什么不是并行呢?计算机只有一个 CPU所以只能支持一个线程运行。有人拍砖说:我家里计算机是多核CPU可以同时支持多个线程运行,确实是这样,为此我也特地去百度了一下有如下几点认 知:

        1、虽然是多核CPU但是,系统总线,内存是共用的,在加载内存数据时仍然需要串行访问。

        2、目前的程序设计语言仍然是过程型开发,没有和好的方法能自动的切割任务使并行计算。

        3、操作系统在线程调度时随着内核的增加复杂性递增,目前最多支持8核

        所以基于以上认知,我们在讨论并发和同步这个问题时仍然按照CPU单核来讨论。

        那么计算机是如何做到一边播放歌曲一边支持文档编辑呢?操作系统会把CPU的执行时间划分微妙级别的时间片段,每一个时间片内去调度一个线程执行,多 个线程不断的切换执行,因此在人类可感知的时间段(秒级)内线程是同时执行的,所以多个线程在某个时间段内的同时执行就是并发。

串行、并行和并发如下图所示:

串行并行并发

        互联网应用基本上都是支持多用户多请求同时访问服务器端的,所以互联网应用都是支持并发的,那么高并发的主要困难是什么呢?操作系统会给每个线程分配 独立的内存空间和时间片,所以线程间是隔离的。但是如果线程访问线程外的内存空间,文件系统,输入输出设备,数据库或者其他存储设备时就会发生资源竞争, 共享资源的访问必须串行,保证串行访问资源的机制就是同步,JAVA中经常使用的同步机制有synchronized关键字,java.util.concurrent.locks.Lock系列类。

  同步的场景有以下几种:

  1、线程获取同步锁,获取失败则阻塞等待

同步1

  适用场景:

  a、同步获取序列号生成器,当有其他线程获取序列号时,其他线程等待

  java代码实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class SynchronizedProcessorimplements Processor {
  
    /* (non-Javadoc)
     * @see com.sunhaojie.test.thread.Processor#process(java.lang.String)
     */
    public void process(String name) {
        System.out.println(String.format("%s开始处理,当前时间是%d", name,
System.currentTimeMillis()));
        synchronized (this) {
            System.out.println(String.format("%s获得锁%s", name,
this.toString()));
            try {
                System.out.println(String.format("%s开始sleep", name));
                Thread.sleep(1000);
                System.out.println(String.format("%s结束sleep", name));
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(String.format("%s释放锁%s", name,
this.toString()));
        System.out.println(String.format("%s结束处理,当前时间是%d", name,
System.currentTimeMillis()));
    }
  
}

  2、线程获取同步锁,获取失败结束

同步2

  适用场景:

  a、定时任务,前一个处理线程未完成时,新线程不能获取锁则直接结束

  java代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class LockFailCloseProcessorimplements Processor {
    private static Lock lock = new ReentrantLock();
  
    /* (non-Javadoc)
     * @see com.sunhaojie.test.thread.Processor#process(java.lang.String)
     */
    public void process(String name) {
        System.out.println(String.format("%s开始处理,当前时间是%d", name,
System.currentTimeMillis()));
        if (lock.tryLock()) {
            System.out.println(String.format("%s获得锁%s", name,
this.toString()));
            try {
                System.out.println(String.format("%s开始sleep", name));
                Thread.sleep(1000);
                System.out.println(String.format("%s结束sleep", name));
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.unlock();
            System.out.println(String.format("%s释放锁%s", name,
this.toString()));
        }else {
            System.out.println(String.format("%s没有获得锁直接退出",
name));
        }
        System.out.println(String.format("%s结束处理,当前时间是%d", name,
System.currentTimeMillis()));
    }
}

  3、线程获取同步锁后,因为其他资源不满足暂时释放同步锁,等待唤醒

同步3

  适用场景:

  a、即使通讯中,发送者获取同步锁发现队列写满时,释放锁等待接收者读取数据

  java代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class SynchronizedWaitWriteProcessorimplements Processor {
  
    /**
     * 是否可读标记,false:不可读,可写 true:可读,不可写
     */
    public static int maxSize = 5;
    public static List<String> content = new ArrayList<String>();
  
    /* (non-Javadoc)
     * @see com.sunhaojie.test.thread.Processor#process(java.lang.String)
     */
    public void process(String name) {
        System.out.println(String.format("%s开始处理,当前时间是%d", name,
System.currentTimeMillis()));
        synchronized (content) {
            System.out.println(String.format("%s获得锁%s", name,
this.toString()));
            try {
                if (content.size() == maxSize) {
                    System.out.println(
String.format("%s临时释放锁%s", name, this.toString()));
                    content.wait();
                }
                System.out.println(
String.format("%s开始写入信息", name));
                Random random = new Random();
                for (int i = 0; i < maxSize; i++) {
                    content.add(
String.format("写入信息%d", random.nextInt(1000)));
                }
                System.out.println(
String.format("%s结束写入信息", name));
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
            content.notify();
        }
        System.out.println(String.format("%s释放锁%s", name,
this.toString()));
        System.out.println(String.format("%s结束处理,当前时间是%d", name,
System.currentTimeMillis()));
    }
  
}

  4、线程获取同步锁后,因为其他资源不满足结束线程

  适用场景:

同步4

  a、即使通讯中,接收者获取同步锁发现队列无数据时,释放锁结束线程

  java代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class SynchronizedWaitReadProcessorimplements Processor {
  
    /* (non-Javadoc)
     * @see com.sunhaojie.test.thread.Processor#process(java.lang.String)
     */
    public void process(String name) {
        System.out.println(String.format("%s开始处理,当前时间是%d", name,
System.currentTimeMillis()));
        synchronized (SynchronizedWaitWriteProcessor.content) {
            System.out.println(String.format("%s获得锁%s", name,
this.toString()));
            if (SynchronizedWaitWriteProcessor.content.size()
!=0) {
                System.out.println(
String.format("%s开始读出信息", name));
                for (int i = 0;
i < SynchronizedWaitWriteProcessor.content.size(); i++) {
                    System.out.println("读出信息:"+ SynchronizedWaitWriteProcessor.content.get(i));
                }
                System.out.println(
String.format("%s结束读出信息", name));
            }
            SynchronizedWaitWriteProcessor.content.notify();
        }
        System.out.println(String.format("%s释放锁%s", name,
this.toString()));
        System.out.println(String.format("%s结束处理,当前时间是%d", name,
System.currentTimeMillis()));
    }
  
}

  最后送上运行以上程序的main方法和Processor 接口类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public interface Processor {
    public void process(String name);
}
public class ThreadTest {
  
    public static void main(String[] args) throws InterruptedException {
        //测试SynchronizedProcessor
        //        Processor processor = new SynchronizedProcessor();
        //        for (int i = 0; i < 10; i++) {
        //            ProcessorThread threadProcessor =
new ProcessorThread("name" + i, processor);
        //            threadProcessor.start();
        //        }
  
        //测试LockProcessor
        //        Processor processor = new LockProcessor();
        //        for (int i = 0; i < 10; i++) {
        //            ProcessorThread threadProcessor =
new ProcessorThread("name" + i, processor);
        //            threadProcessor.start();
        //        }
  
        // Processor processor = new LockFailCloseProcessor();
        // for (int i = 0; i < 10; i++) {
        // ProcessorThread threadProcessor =
new ProcessorThread("name" + i,
        // processor);
        // threadProcessor.start();
        // }
  
        Processor readProcessor = new SynchronizedWaitReadProcessor();
        ProcessorThread readThreadProcessor =
new ProcessorThread("read", readProcessor);
        readThreadProcessor.start();
        Processor writeProcessor = new SynchronizedWaitWriteProcessor();
        ProcessorThread writeThreadProcessor =
new ProcessorThread("write", writeProcessor);
        writeThreadProcessor.start();
        Thread.sleep(100);
        ProcessorThread read2ThreadProcessor =
new ProcessorThread("read2", readProcessor);
        read2ThreadProcessor.start();
    }
}

  多线程可以大大提高性能,但是多线程的同步又增加了应用的复杂性,是否能平衡多线程的性能和复杂性是是否有高并发经验的要求。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 液相色谱柱柱压柱压高怎么办 手机销卡存的钱怎么办 41周宫颈未成熟怎么办 运费险拒绝理赔怎么办 淘宝运费险拒赔怎么办 订单险的运费怎么办 拼多多要换货怎么办 大件退货运费险怎么办 冲浪助手退订了怎么办 小蓝车押金退不了怎么办 小蓝车押金没退怎么办 有订单险退货怎么办 订单险交不了怎么办 小孩手机瘾大不写作业怎么办 运费险不到账怎么办 淘金币要过期怎么办 手机一直扣费怎么办 手机卡自动扣费怎么办 淘宝退货运费险不赔怎么办 类目不能开直通车怎么办 淘宝虚拟恶意退款怎么办 淘宝虚拟单退款怎么办 虚拟物品被骗了怎么办 网络选修课挂了怎么办 美团商家退出怎么办 卖家版运费险太贵了怎么办 美瞳没有客源怎么办 购物车满了怎么办 手机程序无响应怎么办 三星手机无响应怎么办 游戏无响应了怎么办 手机百度无响应怎么办 新手机响应慢怎么办 vivo手机无响应怎么办 vivo软件无响应怎么办 退货商家不处理怎么办 淘宝页面变小了怎么办 淘宝卖家让微信交易被骗怎么办 苹果下载特别慢怎么办 淘宝没有支付宝怎么办 淘宝买东西限购怎么办