公众号merlinsea
线程的状态转换流程
NEW 新建态:线程一旦创建及处于这个状态
Runnable运行态,可以被JVM执行的状态
blocked阻塞态:通常是没有获取锁资源所处于的状态
waiting等待态:某个线程显示调用自己所获取锁的wait方法,如果没有其他线程唤醒,那么将一直得不到调度
time waiting 超时等待态:某个线程显示调用自己所获取锁的wait方法并指定最大等待时间,如果超出最大等待时间没有被唤醒将自动被唤醒
terminated终止态:线程执行完毕
obj.wait():在某个线程中调用该方法,表示该线程进入挂起等待状态,后续代码暂停执行,只有被其他线程唤醒以后才能执行,并且释放持有的锁!!
obj.notify():随机唤醒挂起在obj对象上的【一个】等待线程
obj.notifyAll():唤醒挂起在obj对象上的【所有】等待线程
注意点:
1、调用wait()和notify()方法的线程必须是持有锁的线程
2、当前线程持有的锁和调用wait和notify方法的对象obj必须是同一个对象
3、线程调用wait方法挂起以后会释放自己持有的锁
public class WaitDemo implements Runnable { private static Object waitObj = new Object(); @Override public void run() { //持有资源 synchronized (waitObj) { System.out.println(Thread.currentThread().getName()+"占用资源"); try { waitObj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"释放资源"); } } public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new WaitDemo(),"对比线程"); thread.start(); Thread.sleep(3000L); synchronized (waitObj) { waitObj.notify(); } } }
在上诉代码的基础上增加了一个线程,会发生死锁现象
分析如下:
1、对比线程1会先获取到锁,然后进入wait状态(挂起在waitObj锁上),并释放锁资源
2、主线程继续执行,创建了对比线程2,对比线程2发现锁空闲,就可以持有锁进入syncronized方法体
3、对比线程2执行到wait语句,也挂起在waitObj锁上,并释放当前持有的锁
4.1、主线程继续执行到notify()方法,会随机唤醒挂起在waitObj上的一个线程,然后这个线程继续执行完毕以后释放锁,剩余的一个线程将继续挂起在waitObj上且没有其他线程唤醒,导致发生死锁
4.2、主线程继续执行到notifyAll()方法,会唤醒挂起在waitObj上的全部线程,然后所有线程执行完毕,不发生死锁
但后续主线程已经执行完毕了,也就是没有线程去主动唤醒对比线程2,导致线程2一直处于挂起状态,产生死锁!!!
public class WaitDemo implements Runnable { private static Object waitObj = new Object(); @Override public void run() { //持有资源 synchronized (waitObj) { System.out.println(Thread.currentThread().getName()+"占用资源"); try { waitObj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"释放资源"); } } public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new WaitDemo(),"对比线程1"); thread.start(); Thread thread2 = new Thread(new WaitDemo(),"对比线程2"); thread2.start(); Thread.sleep(3000L); synchronized (waitObj) { waitObj.notify(); //waitObj.notifyAll(); } } }
vip算法班永久学习班: 800元/人
周一、周三、周五:8:30-9:30,周六、周日:10:30-11:30
报名方式:通过公众号导航栏的刷题群即可联系到我的微信号
vip永久班算法训练营
奔跑的小梁,公众号:梁霖编程工具库算法训练营快来参加吧~