多线程状态转换图
关键词
Synchronized
简述:
在Java中,每一个对象都拥有一个锁标记(monitor),也称为监视器,多线程同时访问某个对象时,线程只有获取 了该对象的锁才能访问。所以synchronized 是一个悲观锁。
使用方法:
修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁(monitor)。
修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁(monitor)。
修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁(monitor)。
volatile变量
并发编程三要素:
原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
可见性:指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
有序性:即程序执行的顺序按照代码的先后顺序执行。在多线程下,可能会导致程序以不正确的顺序执行。
volatile关键字作用
使某个变量取消线程缓存机制,使多个线程操作同一个变量,而不是各自修改副本,并有以下作用。
1.保证了不同线程对这个变量进行操作时的可见性,一个值的改变,其他线程立马可见。
2.防止进行指令重排序。
start方法
start()方法是Thread的类方法,尝试通过JVM产生线程。注意:start只是把线程切换为就绪态,几个线程顺序start无法保证顺序执行。
yield方法
yield()被称为退让,让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。不会让出资源锁。
sleep方法
sleept()方法是Thread的类方法,使用sleep方法使线程进入阻塞状态,到达时间后进入就绪状态,不会让出锁,只会让出CPU。
join方法
join()方法是Thread的类方法,实际把多线程的并行操作,变成串行操作。“主”线程实际调用了wait方法,进入阻塞状态,在子线程运行结束后,主线程重新回到就绪状态。
wait方法
wait()方法是object的类方法,因为需要获取到对象的监视器。所以同时也得在Synchronized代码块内。使用此方法使线程进入等待队列和阻塞状态。需要使用notify/notifyAll唤醒进入锁池/同步队列。才有可能获得锁,进入就绪状态。相当于PV操作中的P操作。
notify/notifyAll方法
notify()/notifyAll()方法是object的类方法,因为需要获取到对象的监视器。所以同时也得在Synchronized代码块内。使用此方法可以唤醒该对象的等待队列中一个线程,notifyAll则唤醒所有。相当于PV操作中的V操作。
相关算法
CAS算法
CAS是英文单词Compare And Swap的缩写,是一个乐观锁,非阻塞算法,需要volatile变量。
CAS原理:通过把并发问题转嫁成原子操作,利用CPU或者说是JVM指令实现。
CAS过程:需要三个值 内存 预期值 新的值,如果不符合预期值,就终止操作,循环下一次操作。
CAS缺点:
1:ABA问题:可以通过追加版本号解决。
2:高并发问题时:大部分线程全部操作失败,占用大量资源,且效果很差。
3:只能保证一个共享变量的原子操作:可以将多个变量视作一个对象,一起操作。
引用出处
Synchronized部分内容 https://www.cnblogs.com/dolphin0520/p/3923737.html
https://blog.csdn.net/javazejian/article/details/72828483
yield方法 https://blog.csdn.net/Terrence_he/article/details/78333753