转载

Java 多线程的总结(一)

最近研读《Java并发编程实战》 这一本书,作者也是 java current 并发包的作者写的这本书,我也是通过极客时间中的一个课程了解到这本书,于是马上下单买下了这本书,我这里就说重点吧,我通过课程和自己看书有以下的收货,希望也对你有所帮助。

这周我主要分享以下四个知识点:

  • 从宏观和微观角度认识并发编程,钻进去看本质,跳出来看全景这个学习方法
  • Java 并发变编程的原因: 可见性、原子性、有序性
  • 类锁和对象锁;公平锁和非公平锁;可重入锁;细粒度锁和粗粒度锁
  • 如何避免死锁

学习方法

这里主要是想分享的是,研究一个问题,我们要抓住知识的核心,第一学习这个知识点是来干什么的,第二知道这个知识点的优点和缺点,以便于自己知道自己应该在什么场景下应用到他,和自己的知识体系相融合,第三要查看的实现原理,因为如果应用到项目中,你要知其然,知其所以然,才能真正的了解这个知识点,那么我们那并发编程这个知识点当做案例来分析一下:

  1. 这个知识点是干什么的?

    这个知识点是用来解决高效性能优化的问题的,就比如愚公移山,他一个人搬一座山一辈子也搞不定,就有如单线程来做一个耗时任务,但是如果用多线程来解决这个问题,就有可能把整座山搬完,如果线程够多的话,多线程主要是高效利用计算机多核CPU 的性能。

  2. 优点和缺点

    优点就是充分利用的计算机的性能,可以多个任务并行,缺点如果没有正确使用,容易出现并发问题,比如线程等待、死锁等等问题。

  3. 原理实现

​ 线程的实现主要是靠管程来实现,Java 内部的 sycnized 和 lock condition 来实现,通过 notify wait notifyall 来控制线程的切换

并发编程Bug 的来源 : 可见性、原子性、有序性

并发编程会出现问题,这些问题是如何导致的呢? 如果单线程处理一个事务的时候,就不会出现问题,比如对于局部变量会存在栈空间,还有我们平时使用的 Threadlocal 的,他都是通过Map 存储每个线程的标识,也是响相当于单线程处理问题,这样也不会出现并发问题。

我们出现并发问题,主要是因为我们现在大部分都是 多核CPU, 每一个任务都是线程处理的,而操作系统里有进程和线程的概念,一个进程可以持有多个线程,线程的创建是在进程的复制基础上,引用加1的操作,我们用多线程处理,通过CPU 分配到时间片后在处理任务的。

因为CPU 处理一天,内存处理一年,内存处理一天,IO 处理十年,这样悬差的处理方式下,根据木桶原理,看最短的那个木板制约着能装载多少水,所以操作系统增加了CPU 缓存、编译优化 来解决同步问题,Java 内存模型,Happen-Before 原则。

因为CPU 缓存执行到线程切换导致可见性问题,高级语言的指令有多条CPU 的指令,在线程切换处理的时候会出现原子性问题,还有DCL 写法如果不加volitate 修饰符的话,分配内存,赋值,创建对象的顺序会发生改变,会导致空指针,这样会导致有序性问题。

锁在实践当中的使用方法

我们平时在面试中被问到的常见的就是有如下:类锁和对象锁;公平锁和非公平锁;可重入锁;细粒度锁和粗粒度锁,那么我们就一一解释这几个问题

类锁和对象锁

锁的是clas文件结或者静态方法就是类锁,如果锁的是this、成员变量、非静态方法 则是对象锁,这两种锁不是一个范围没有互斥的效果

公平锁和非公平锁

如果A、B、C 三个线程竞争一把锁,如果线程A 一直持有这个锁,如果线程A 释放这个锁,B、C 都有可能获得这个锁,但是在某种情况下,B 比C 等待的时间长,如果是公平锁的话,B 就可以优先

细粒度锁和粗粒度锁

还是以上边的例子为,这里描述一个业务场景,在转账的操作需要addMoney 和 reduceMoney 两个方法进行加锁,如果直接锁对象,这两个操作只能串行,但是如果对 两个操作分别用自己的锁,lock1 锁和lock2 锁,这样就可以同时进行,加快了效率。

死锁

并发在任何一门里都是高级知识点,并发如果处理不当就会产生并发问题,如果上述操作转账操作,细粒度锁提升了性能,但是这里会出现死锁的问题,如果线程 T1 用户A 给B 转账, T1 持有 A 对象的锁,此时T2线程下 B给 转账 A,T2持有B 对象的锁,T1 等待B 对象的锁,T2等待A 对象的锁,从而形成了死锁 ,这里《Java 并发编程实战》里边提倡三个使用并发的三个原则可以避免死锁。

  1. 优先使用成熟的并发工具类
  2. 迫不得已才使用低级的同步原语言
  3. 避免过早优化,出现瓶颈后在进行优化
原文  https://juejin.im/post/5ddaa7ab6fb9a07ab75bc9f9
正文到此结束
Loading...