实战java高并发程序设计读书笔记一

基本概念

同步异步

   同步和异步这两个是相对的概念用来描述方法的调用。同步指的是方法调用开始方法的调用者必须等待方法调用返回时,才能进行下一步操作。而相对的概念异步就是相反,调用者不需要进行等待。

并发并行

   并发和并行两个概念特别的容易混淆,他们都表示两个以上的任务一起的执行,但是两个概念却又有稍微的区别。并发偏向于有多个相同的任务一起需要执行,具体的执行方式一般来说指的都是交替进行;而并行则是指通过多个异步执行的任务来完成一个整体的大的任务。

临界区

  临界区用来表示一种公共资源或者是共享的数据,可以被多个线程使用到。但是每次当有线程在使用者一个临界区的时候其他的线程必须等待,直到前一个退出之后才能使用。并行程序的难点就是有效的对于临界区的使用权进行管理和保护。

阻塞非阻塞

  阻塞和非阻塞通常用来形容多线程之前的互相影响。比如一个线程占用了临界区的资源,那么其他需要使用这个临界区的线程必须等待,等待会导致线程的挂起,这就是阻塞。反之当所有线程都会尝试不断向前执行,这个就是非阻塞。

死锁饥饿活锁

   这三个概念都属于线程的活跃性问题,基本上死锁是里面情况最糟糕的一种,这种情况中线程之后互相持有继续推进需要的资源,在程序中永远都没法往下进行。

   饥饿是在程序中的某个线程迟迟没能获取到推进所需要的资源,可能由于种种原因,优先级或者纯粹是概率问题,一般来说随着程序压力的下降饥饿的情况会很快得到缓解。

   活锁发生在当线程进行资源谦让的时候,资源将在需要它的线程之前来回的跳转,但是没有线程能够继续

 

并发级别

阻塞

  就像概念中的阻塞差不多,一个线程若是阻塞的在其他线程释放资源前这个线程将一直处于挂起状态无法继续执行,一般来说在java中使用关键字synchronized关键字或者是重入锁时我们得到的就是阻塞的线程

无饥饿

线程之间的优先级是比较容易造成饥饿的原因,当由于某个线程优先级过低,并且系统中高优先级的线程过多的时候那么就会造成饥饿。所以如果一个机制是完全按照等待时间来进行分配资源的这个就是公平的线程机制,也就是无饥饿的。

无障碍

无障碍是一种最弱的非阻塞调度,所有线程都能自由的进入临界区,在执行过程中进行判断是不是有冲突,如果发生冲突那么就直接回滚数据,保证正确性。

所以在这种高并发情况下,所有线程都有可能在不断回滚自身的操作,导致没有一个线程能顺利往下执行

无锁

无锁的典型特点就是可能会包含一个无限循环,在这个循环中线程会不断的尝试修改共享的变量。如果没有冲突那么就修改成功,否则继续尝试修改

无等待

无等待是在无锁的基础上更进一步的扩展,要求所有线程都在有限步内完成,其思想有点像git的操作,每个线程持有副本进行操作,最终将改动写回原数据

 

两个概念性的定律

 

Amdahl定律

  这个定律的核心就是假设硬件拥有无限的cpu那么当程序的并行化率越高程序的加速比越高,也就是在核心充足的情况下我们可以尽量使用并行来提高效率

Gustafson定律

  这个定律的核心就是假设并行化的比例足够高的时候,只需要增加处理器的数量就能提高加速的效果。

 反之我们可以看到如果在CPU的数量远小于并行线程的数量的时候执行的效率会受到CPU数量的制约

Java相关并发的内容

 

原子性(Atomicity)

   原子性指的是一个操作是不可中断的,正如他的名字那样,已经是最小的划分,所以在完成这个操作之前其他的线程无法在中间进行其他的操作,也就不能影响这个操作。

   原子性一个比较常见的例子就是i++,在这个过程中可以分为几个步骤

T = i

i = T+1

所以一旦这个过程遭到并发的影响那么i的值就无法被预知了

可见性(Visibility)

   可见性是指当一个线程修改了某个共享变量的值其他线程是不是能立即获取到这个修改

    相对来说可见性是一个综合性的问题,除了缓存和硬件的优化会导致可见性的问题之外,指令重排等也会导致这类问题

有序性(Ordering)

   有序性的产生原因主要是JVM虚拟机的优化,指令重拍机制,这有可能导致执行的先后顺序不同,在并行的程序中就有可能造成这个问题。



你可能感兴趣的:(开卷有益,并发,性能优化,java)