zoukankan      html  css  js  c++  java
  • Java并发编程

    互联网的快速发展,Java开发的过程或多或少会需要进行并发编程,也会遇到一些并发编程带来的各种bug。下面从并发编程的理论、并发工具类、并发设计模式、并发模型案例,记录一下自己的学习历程。
    1.并发编程理论

    并发编程的来源于缓存导致的可见性问题,线程切换带来的原子性问题,编译优化带来的有序性问题。Java语言规范引入了Java内存模型,通过定义多项规则对编译器和处理器进行限制,主要是针对可见性和有序性。主要是通过volatile、synchronized 和 final 三个关键字,以及Happens-Before 规则。
    (1)锁,锁操作是具备happens-before关系的,解锁操作happens-before之后对同一把锁的加锁操作。实际上,在解锁的时候,JVM需要强制刷新缓存,使得当前线程所修改的内存对其他线程可见。
    (2)volatile字段,volatile字段可以看成是一种不保证原子性的同步但保证可见性的特性,其性能往往是优于锁操作的。但是,频繁地访问 volatile字段也会出现因为不断地强制刷新缓存而影响程序的性能的问题。
    (3)final修饰符,final修饰的实例字段则是涉及到新建对象的发布问题。当一个对象包含final修饰的实例字段时,其他线程能够看到已经初始化的final实例字段,这是安全的。
    Happpens-Before规则:
    (1)程序次序规则:在一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作。准确地说,应该是控制流顺序而不是程序代码顺序,因为要考虑分支、循环等结构。
    (2)管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。这里必须强调的是同一个锁,而"后面"是指时间上的先后顺序。
    (3)volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作,这里的"后面"同样是指时间上的先后顺序。
    (4)线程启动规则:Thread对象的start()方法先行发生于此线程的每一个动作。
    (5)线程终止规则:线程中的所有操作都先行发生于对此线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测到线程已经终止执行。
    (6)线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生。
    (7)对象终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始。
    Java内存中的原子性是通过管程synchronized来实现互斥性,保证操作的原子性。Java中synchronized有一个隐形规则:当修饰静态方法的时候,锁定的是当前类的 Class 对象;当修饰非静态方法的时候,锁定的是当前实例对象 this。
    当然synchronized一次只能锁定一个对象,怎么通过通过锁来锁定多个资源?当然我们可以将需要进行的动作一次锁定,可以通过锁定当前类或静态方法。但是这样锁的颗粒度大,造成程序性能低。用不同的锁对受保护资源进行精细化管理,能够提升性能。当然这样又会造成死锁的情况出现。要避免死锁就需要分析死锁发生的条件,有个叫 Coffman 的牛人早就总结过了,只有以下这四个条件都发生时才会出现死锁:
    (1)互斥,共享资源 X 和 Y 只能被一个线程占用;
    (2)占有且等待,线程 T1 已经取得共享资源 X,在等待共享资源 Y 的时候,不释放共享资源 X;
    (3)不可抢占,其他线程不能强行抢占线程 T1 占有的资源;
    (4)循环等待,线程 T1 等待线程 T2 占有的资源,线程 T2 等待线程 T1 占有的资源,就是循环等待。
    等待 - 通知机制是一种非常普遍的线程间协作的方式,notify() 是会随机地通知等待队列中的一个线程,而 notifyAll() 会通知等待队列中的所有线程,所以除非经过深思熟虑,否则尽量使用 notifyAll()。

    CPU 密集型计算:
    对于 CPU 密集型的计算场景,理论上“线程的数量 =CPU 核数”就是最合适的。不过在工程上,线程的数量一般会设置为“CPU 核数 +1”,这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以顶上,从而保证 CPU 的利用率
    I/O 密集型:
    最佳线程数 =CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]
    2.并发工具类

    3.并发设计模式

    4.并发模型案例

    完整版参考:https://www.jianshu.com/p/d417684f4f59

  • 相关阅读:
    2020软件工程作业04
    2020软件工程作业03
    2020软件工程作业02
    2020软件工程作业01
    Linux操作系统分析-课程学习总结报告
    结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程
    深入理解系统调用
    基于mykernel 2.0编写一个操作系统内核
    交互式多媒体图书平台的设计与实现
    码农放入自我修养之必备技能学习笔记
  • 原文地址:https://www.cnblogs.com/Johar/p/12250673.html
Copyright © 2011-2022 走看看