学习高并发之前了解的一些概念:
同步(Synchronous):同步方法调用一旦开始,调用者必须等到方法调用返回后才能进行后续行为。
异步(Asynchronous):异步方法更像一个消息传递,一旦开始,方法调用会立刻返回,调用者可以继续进行后续操作,而异步方法通常会在另外一个线程中“真实”地执行。
并发(Concurrency):偏重于多个任务交替执行,多个任务之间还有可能串行
并行(Parallelism):多个任务同时执行
临界区:表示一种公共资源或是共享数据,可以被多个线程使用,但每一次只能有一个线程使用它,一旦临界区资源被占,其他线程想要使用必须等待。
阻塞(Blocking):一个线程占用了临界区资源,那么其他所有需要这个资源的线程都必须在这个临界区中等待。等待导致线程挂起,这就是阻塞。
非阻塞(Non-Blocking):强调没有一个线程可以妨碍其他线程执行,所有线程都会尝试不断向前执行。
死锁(Deadlock):两个或两个以上线程执行过程中由于竞争资源或由于彼此通信而造成的一种阻塞现象,若无外力作用他们都无法推进下去。
饥饿(Strvation):指一个或多个线程因种种原因无法获得所需要的资源,导致一直无法进行。
活锁(Livelock):两个线程之间互相主动让出资源给别人使用,那么导致资源在两者之间不停跳动,没有一个线程可以拿到资源。
并发级别
有阻塞、无饥饿、无障碍、无锁、无等待这几种。
1.阻塞:使用synchronized关键字或可重入锁时,我们得到的就是阻塞的线程。
2.无饥饿:如果锁是公平的满足先来后到那么就不会有饥饿产生。
3.无障碍:是一种最弱的非阻塞调度。两个线程如果无障碍执行,那么他们就不会因为临界区的问题导致一方被挂起。无障碍线程一旦检测到这种情况会立刻对修改进行回滚,保证数据安全。是一种乐观机制。通过一种“一致性标记”实现,线程操作之前会读取并保存这个标记,操作完之后如果标记不一致说明数据被修改需要重试操作。
4.无锁:无锁的并行都是无障碍的。无锁的并发保证必然有一个线程能够在有限步内完成操作离开临界区。
5.无等待:要求所有的线程都必须在优先步内完成,这样就不到引起饥饿问题。
JMM
1.原子性(Atomicity):一个操作是不可中断的。即使在多个线程一起执行的时候,一个操作一旦开始就不会被其他线程干扰。
2.可见性(Visibility):当某一个线程修改了某一个共享变量的值,其他线程能否立即知道这个修改。
3.有序性(Ordering)
哪些指令不能重排:Happen-Before规则
●程序顺序原则:一个线程内保证语义的串行性
●volatile规则:volatile变量的写,先发生于读,这保证了volatile 变量的可见性
●锁规则:解锁(unlock)必然发生在随后的加锁(lock) 前
●传递性:A先于B,B先于C,那么A必然先于C
●线程的start()方法先于它的每一个动作
●线程的所有操作先于线程的终结(Thread.join())
●线程的中断(interrupt() )先于被中断线程的代码
●对象的构造函数执行、结束先于finalize()方法