Java高并发设计-----走进并行世界-----1

走进并行世界

1.1何去何从的并行计算

1.1.2摩尔定律

Linus Torvalds:Linux大佬:并行计算智能在图像处理和服务端编程两个领域使用,并且它在着两个领域有着广泛的使用,但是在其它任何地方,并行计算毫无建树!

概念:硬件每18个月性能翻一倍

很显然没有办到!!!

所以只能软件来凑了

1.2必须知道的几个概念

1.2.1同步和异步

同步:只有执行完前一步,才能进行接下来的操作

异步:调用方法后直接返回,随后执行接下来的步骤。不需要等待调用的方法产生结果。被调用的方法通常在另外一个线程上执行。整个过程不会阻碍调用者继续后续的操作

1.2.2并发(Concurrency)和并行(Parallelism)

并发:CPU高速的切换,以至于觉的两个线程在一起执行

并行:真实的两个线程同时执行

1.2.3临界区

多线程使用的共享资源,但是每一次只能有一个线程使用它,一旦临界区资源被占用,其它线程必须等待前一个线程执行完成之后才能占有。

1.2.4阻塞(Blocking)和非阻塞(Non-Blocking)

阻塞:线程因为临界区资源产生了等待

非阻塞:不用等待(具体概念,日后补充

1.2.5死锁(Deadlock)、饥饿(Starvation)、活锁(Livelock)

死锁:例如有两个妹子x和y,A占有x,B占有y;但是A不想抛弃x的情况下得到y,B不想抛弃y的情况下得到x;所以AB两个老渣男尬住了,争执不下。

饥饿:好理解为,老备胎了,CPU一直就是不执行它,它一直等待。

活锁:线程A需要资源x,线程B需要资源x;A、B同时觉得你让给你吧,结果A、B同时礼让了,然后谁都没得到;然后A、B又同时要x,结果又都礼让了。

1.3并发级别

应该是指并发的程度吧,不知道这个是衡量什么的

1.3.1阻塞

为了资源,互相等待;用锁就会产生等待

1.3.2无饥饿

提交的线程一定能被执行,不会不执行

1.3.3无障碍

每个线程都可以肆无忌惮的获得临界区资源

无障碍:一种乐观的策略,任务线程不会发生冲突。

策略:一致性标记-----------将公共资源标记,操作前,先读取并保存标记,操作完成后,再次读取,检查标记是否修改,如果一致,就说明资源访问没有冲突。如果不一致,就重试;每个线程修改数据都会修改标记。

1.3.4无锁

所有线程对临界区进行访问,所有线程都无限循环的修改数据,直到一个修改成功,然后退出。说实话不懂!

1.3.5无等待

在无锁的基础上,增加一个在有限步的基础上内完成线程任务

1.4并行重要定律

1.4.1Amdahl定律

1.4.2Gustafson定律

 1.5JMM

Java内存模型(JMM)-----现在还不是很了解

1.5.1原子性

原子性:指一个操作是不可终端的

1.5.2可见性

一个线程修改了某一个共享变量的值时,其它线程能够立即了解到这个修改

1.5.3有序性

有序性:要保证一些代码执行必须在另外一些代码前面

一般情况下有序,但是有时候会发生指令重排

指令重排:保证了串行语义的一致,但是没有保证多线程间的语义一致性

  为什么会发生指令重排:

因为CPU采用的是流水线执行,所以Java虚拟机和执行系统会对指令进行一定的重排,来满足流水线执行!!!自己想想就明白咯,阿喆!!!

1.5.4哪些指令不会重排:Happen-Before规则

  • 程序顺序规则:一个线程内保证语义的串行性。
  • volatile规则:volatile变量的写先于读发生
  • 锁规则:解锁一定在加锁之前。
  • 传递性:A先于B,B先于C,那么A势必先于C
  • 线程的start()方法先于它的每一个动作
  • 线程的所有操作先于线程的终结(Thread.join())
  • 线程的中断(interrupt())先于被中断线程的代码。
  • 对象的构造函数的执行、结束先于finalize()方法 
原文地址:https://www.cnblogs.com/sicheng-li/p/13033546.html