关键字:线程状态、ObjectMonitor
状态分类
(1)新建状态(NEW),执行new Thread()后的状态;
(2)就绪状态(RUNNABLE),执行start方法,等待CPU时间片;
(3)运行状态(RUNNING),获得CPU时间片后的状态,注意,线程只能从就绪状态转到运行状态,其他状态不行;
(4)同步阻塞,无法获得同步锁,由运行状态转到同步阻塞,获得锁以后回到就绪状态;
(5)无限等待,调用了wait、sleep、join方法,运行状态转到无限等待 ,等待被notify或notifyAll或中断或其他线程执行完回到就绪状态;
(6)有限等待,线程执行了wait(timeout)、sleep(timeout)、join(timeout)方法,运行状态转到有限等待状态,timeout、notify或notifyAll或中断回到就绪状态;
(7)死亡状态(TERMINATED),线run方法正常或异常执行完,运行状态转到死亡状态。
状态转换
状态切换.pngObjectMonitor
每个Java对象都有一个对应的ObjectMonitor对象,它实现了同步机制,这就是为什么Object对象都能当成锁的原因。
ObjectMonitor是如何实现同步机制?
ObjectMonitor有几个关键属性:
(1)owner,指向持有ObjectMonitor的线程;
(2)WaitSet,wait状态的线程队列,等待被唤醒,也就是调用了wait;
(3)EntrySet,等待锁的线程队列,;
同步流程
(1)有两个线程,线程A、线程B将竞争锁访问同步代码块,先进入ObjectMonitor的EntrySet中等待锁;
(2)当CPU调度线程A获取到锁则进入同步代码,ObjectMonitor owner属性指向线程A,线程B继续在EntryList中等待;
(3)线程A在同步代码中执行wait,则线程进入WaitSet并释放锁,ObjectMonitor owner属性清空;
(4)CPU调度使线程B获取到锁进入同步代码块,ObjectMonitor owner属性指向线程B,任务执行完退出同步代码之前调用notifyAll,线程A被唤醒,从WaitSet转到EntryList中等待锁,线程B退出同步代码块,ObjectMonitor owner属性清空;
(5)CPU调度使线程A获取同步锁,继续后续代码;
总结:
(1)线程有新建状态、就绪状态、运行状态、同步阻塞、有限等待、无限等待、死亡状态;
(2)每个Java对象靠ObjectMonitor实现同步;
以上分析有不对的地方,请指出,互相学习,谢谢哦!
网友评论