`

java高并发

    博客分类:
  • java
阅读更多

并发同步知多少

来源:孙豪杰的博客 发布时间:2016-02-26 阅读次数:308
 

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

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

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

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

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

        我们经常在计算机上一边听歌一边写文档(或者处理其他的事情),这就是一种并发行为,表面看两个程序是同时进行,为什么不是并行呢?计算机只有一个 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 SynchronizedProcessor implements 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 LockFailCloseProcessor implements 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 SynchronizedWaitWriteProcessor implements 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 SynchronizedWaitReadProcessor implements 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();
    }
}

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

分享到:
评论

相关推荐

    java高并发写入用户信息到数据库的几种方法

    Java 高并发写入用户信息到数据库的几种方法 在 Java 高并发环境下,写入用户信息到数据库可能会出现一些问题,例如多个用户同时写入导致数据不一致或重复写入。为了解决这些问题,需要使用一些特殊的方法来确保...

    实战Java高并发程序设计(高清版)

    《实战Java高并发程序设计》这本书正是一本专注于这一主题的资源,它旨在帮助读者深入理解如何在Java环境中构建可扩展、高效且稳定的高并发应用。 首先,我们要理解什么是高并发。高并发是指在短时间内系统能够同时...

    java高并发程序设计(原版电子书)

    《Java高并发程序设计》是一本深入探讨Java平台上的并发编程技术的专业书籍,由葛一鸣等人编著。这本书旨在帮助读者理解并掌握在高并发环境下编写高效、稳定且可扩展的Java应用程序的关键技巧和最佳实践。以下是该书...

    实战Java高并发程序设计 中文pdf版下载

    实战Java高并发程序设计主要介绍基于Java的并行程序设计基础、思路、方法和实战。首先,立足于并发程序基础,详细介绍Java中进行并行程序设计的基本方法。第二,进一步详细介绍JDK中对并行程序的强大支持,帮助读者...

    java高并发秒杀api源码

    这个"java高并发秒杀api源码"很可能是一个实现这类功能的示例项目,它结合了Spring和MyBatis两大主流框架,以提升系统性能和可维护性。下面,我们将深入探讨这些关键知识点。 首先,`Spring`是一个全面的企业级应用...

    实战Java高并发程序设计-试读

    《实战Java高并发程序设计》是一本专注于Java并发编程实践的书籍,试读版提供了前两章的内容,为读者提供了一个初步了解并发编程基础的窗口。在Java领域,并发编程是构建高性能、高效率系统的关键技术,对于软件开发...

    Java高并发编程,构建并发编程知识体系,提升面试成功率

    Java高并发编程,构建并发编程知识体系,提升面试成功率,完整版17章视频教程下载。 本课程将结合大量图示及代码演示,带你掌握多线程并发编程(线程安全,线程调度,线程封闭,同步容器等)与高并发处理思路与手段...

    实战Java高并发程序设计第二版随书代码

    《实战Java高并发程序设计》第二版是一本深入探讨Java多线程和并发编程的书籍。这本书涵盖了Java并发编程的核心概念和技术,旨在帮助开发者在实际项目中高效地处理高并发场景。随书附带的代码提供了丰富的示例,以便...

    实战Java高并发程序设计课-视频教程网盘链接提取码下载.txt

    实战Java高并发程序设计课是一门针对Java开发者的培训课程,重点关注如何设计和优化高并发的程序。学员将学习到并发编程的基本概念、线程池的使用、锁机制、并发集合等技术,并通过实际案例进行实践操作。这门课程...

    实战java高并发程序设计.pdf

    《实战Java高并发程序设计》主要介绍基于Java的并行程序设计基础、思路、方法和实战。第一,立足于并发程序基础,详细介绍Java中进行并行程序设计的基本方法。第二,进一步详细介绍JDK中对并行程序的强大支持,帮助...

    实战Java高并发程序设计课件

    本课程“实战Java高并发程序设计”旨在深入探讨如何有效地处理和优化Java应用程序中的多线程和并发问题。 首先,我们要理解Java高并发的核心概念。并发是指多个执行单元(如线程或进程)在一段时间内同时执行,而...

    实战Java高并发程序设计 .pdf 下载

    实战Java高并发程序设计 葛一鸣 / 郭超 著 高清 带目录下载 内容简介: 在过去单核CPU时代,单任务在一个时间点只能执行单一程序,随着多核CPU的发展,并行程序开发就显得尤为重要。 《实战Java高并发程序设计》...

    java 高并发解决 思路

    以上只是Java高并发解决思路的一部分,实际应用中还需要结合具体业务场景和性能需求进行选择和优化。"高并发web架构.pdf"文档中的实例将进一步细化这些概念,提供实践指导。在学习过程中,理论与实践相结合,才能更...

    SSM实战项目-Java高并发秒杀API

    SSM实战项目——Java高并发秒杀API 何为秒杀? 所谓“秒杀”,就是网络卖家发布一些超低价格的商品,所有买家在同一时间网上抢购的一种销售方式。由于商品价格低廉,往往一上架就被抢购一空,有时只用一秒钟。 ...

    实战Java高并发程序设计模式

    "实战Java高并发程序设计模式"的主题旨在帮助开发者掌握如何在高并发环境中有效地设计和实现高效的程序。本篇文章将深入探讨相关知识点,包括并发基础、线程安全、同步机制、并发设计模式以及性能优化策略。 1. ...

    java高并发编程推荐超好的一本电子书

    根据提供的信息,我们可以深入探讨Java高并发编程的相关知识点。高并发是现代软件系统设计中一个非常重要的方面,尤其是在云计算和大数据处理领域。下面将详细解释Java高并发编程的基础概念、核心技术以及实现技巧。...

    Java高并发秒杀API之业务分析与DAO层

    总的来说,Java高并发秒杀API的设计需要深入理解业务需求,合理规划系统架构,优化数据库访问,以及充分利用并发处理机制。通过对DAO层的精心设计和优化,我们可以有效地应对高并发挑战,提供稳定、高效的秒杀服务。

    JAVA高并发实践

    JAVA 高并发 实践书籍 附目录JAVA 高并发 实践书籍 附目录JAVA 高并发 实践书籍 附目录

    JAVA并发编程与高并发解决方案 JAVA高并发项目实战课程

    ##### 3.2 Java高并发的关键技术 - **缓存机制**:使用如Redis等缓存技术减少数据库访问压力。 - **负载均衡**:利用负载均衡器(如Nginx)分散请求到不同的服务器节点。 - **异步处理**:通过消息队列(如RabbitMQ...

Global site tag (gtag.js) - Google Analytics