1. while实现线程通信
//线程二需要while轮询 才能实现线程间通信,对cup消耗很大
//线程主动读取 而非对象等待/通知
fun main(args: Array<String>) {
val goods = Goods()
Thread(Runnable { goods.deduction(); Thread.sleep(300); goods.deduction(); }).start()
Thread(Runnable {
do {
Thread.sleep(200)
} while (goods.stock > 3)
println("商品库存减少到小于4")
}).start()
}
2. wait和Notify
- 谁wait对谁上锁. 在调用wait()和notify()之前,线程必须获得该对象的对象级别锁,即只能在(该对象的)同步方法或同步代码块(该对象)中调用wait方法。
- 每个对象的notify()只能唤醒一个wait().如果存在同一对象的多个wait()线程,则随机唤醒一个
- wait()触发后,wait线程被挂起,等到该对象notify()方法触发,wait线程回到可运行状态,与其他线程公平竞争。notify()方法触发后,必须等到对象级别锁释放,也就是sychronized(obj)代码块执行完毕 ,wait线程才能被唤醒.
- wait()触发,wait线程放弃对象锁并挂起该线程。
class WaN{
private val lock = java.lang.Object()
private val goods =Goods()
fun dec(){
synchronized(lock){
for (i in 1..3) {
goods.deduction()
}
lock.wait()
//notify触发以后,线程被唤醒,但wait线程仍然要与其他线程公平竞争
Thread.sleep(200)
println("wait结束...")
}
}
fun dis(){
synchronized(lock){
lock.notify()
Thread.sleep(500)
goods.discount()
//wait的对象级别锁 的notify执行到这里才算结束,也就是说,必须使wait的对象级别锁释放,wait线程才能从挂起状态被唤醒,
//而不是lock.notify行代码执行后,就立即唤醒wait线程
}
}
companion object {
@JvmStatic
fun main(args: Array<String>) {
val WaN = WaN()
Thread(Runnable { WaN.dec() }).start()
Thread(Runnable { WaN.dec() }).start()
Thread.sleep(2000)
Thread(Runnable { WaN.dis() }).start()
}
}
}
3. 线程状态切换

- 线程start()方法执行后,系统会为cpu分配资源,使其处于Runnable状态,这 是一个准备运行阶段,抢到cpu就是Running状态。
- 从Running 到Runnable
每个锁对象都有两个队列:一个是就绪队列,一个是阻塞队列。就绪队列了将要获得锁的线程,阻塞队列存储了被阻塞的线程。
网友评论