android java wait_Android-Java-等待唤醒机制原理

儿时的游戏:(等待 与 唤醒)

有一群小朋友一起玩一个游戏,这个游戏可能大家都玩过,大家一起划拳,划拳输得最惨的那个小朋友去抓人(这个小朋友取名为 CPU),被抓的很多人取名为线程,有很多线程,如果其中一个小朋友(例如:Thread-3) 被木头了(wait();)  就站着不准动了(冻结状态),Thread-3小朋友站着不动(冻结状态) CPU小朋友就不会去抓Thread-3小朋友,因为Thread-3小朋友(释放CPU执行资格)   需要其他小朋友(例如:Thread-5) 去啪一下Thread-3小朋友(notify();),  此时Thread-3小朋友就可以跑了(被唤醒) 此时Thread-3小朋友具备被抓的资格(具备CPU执行资格),能否被抓得到 要看CPU小朋友的随机抓人法(CPU切换线程的随机性)

等待唤醒机制:

wait(); 等待/冻结 :可以将线程冻结,释放CPU执行资格,释放CPU执行权,并把此线程临时存储到线程池

notify(); 唤醒线程池里面 任意一个线程,没有顺序;

notifyAll(); 唤醒线程池里面,全部的线程;

使用等待唤醒注意事项:

1.使用来wait();冻结,就必须要被其他方notify();,否则一直wait()冻结,所以等待与唤醒是配合一起使用的;

2.wait();  notify();  notifyAll(); 等方法必须被synchronized(锁) {包裹起来},意思就是:wait();  notify();  notifyAll();  必须要有同步锁🔒,否则毫无意义;

3.wait();  notify();  notifyAll(); 等方法必须持有同一把锁🔒,因为:lockA.wait();  只能使用 lockA.notify(); / lockA.notifyAll(); , 它们是使用同一把锁🔒的;

等待:🔒锁.wait();

唤醒:🔒锁.notify();

唤醒:🔒锁.notifyAll();

代码分析 1:

❌❌❌❌❌ 错误的示范,public synchronized (锁🔒== this) void testMethod1(){} ,然后却是OBJ_LOCK.notify();     this锁🔒和 OBJ_LOCK🔒不一致,是错误的,没有共用一把锁

private final Object OBJ_LOCK = newObject();/*** public synchronized void testMethod1(){}

* synchronized的锁🔒是this / b = new TestWaitNotifyDemo(); b也是

* 所以可以:this.notify(); this.notifyAll(); this.wait();*/

public synchronized voidtestMethod1() {/*** 唤醒 wait(); 冻结的线程,如果没有就是空唤醒,Java是支持的*/OBJ_LOCK.notify();//注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 唤醒所有*/OBJ_LOCK.notifyAll();//注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 当前自己线程 冻结,释放CPU执行资格,释放CPU执行权,CPU就会去执行其他线程了*/

try{

OBJ_LOCK.wait();//注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

} catch(InterruptedException e) {

e.printStackTrace();

}

}

✅✅✅✅✅,正确的方式:public synchronized(🔒锁==this) void testMethod1, this.notify();  this.notifyAll();  this.wait();

/*** public synchronized void testMethod1(){}

* synchronized的锁🔒是this / b = new TestWaitNotifyDemo(); b也是

* 所以可以:this.notify(); this.notifyAll(); this.wait();*/

public synchronized voidtestMethod1() {/*** 唤醒 wait(); 冻结的线程,如果没有就是空唤醒,Java是支持的*/

this.notify(); //注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 唤醒所有*/

this.notifyAll(); //注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 当前自己线程 冻结,释放CPU执行资格,释放CPU执行权,CPU就会去执行其他线程了*/

try{this.wait(); //注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

} catch(InterruptedException e) {

e.printStackTrace();

}

}

代码分析 1 伪代码:

public synchronized(🔒锁是this) voidtestMethod1() {

锁🔒this.notify(); //注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

锁🔒this.notifyAll(); //注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

锁🔒this.wait(); //注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

}

代码分析 2:

错误的示范❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌  synchronized (锁🔒== OBJ_LOCK) ,然后却是this.notify();  this锁🔒和 OBJ_LOCK🔒不一致,是错误的

private final Object OBJ_LOCK = newObject();public void testMethod2() throwsInterruptedException {/*** synchronized (OBJ_LOCK) {}

* synchronized的锁🔒是 OBJ_LOCK

* 所以可以:OBJ_LOCK.notify(); OBJ_LOCK.notifyAll(); OBJ_LOCK.wait();*/

synchronized(OBJ_LOCK) {/*** 唤醒 wait(); 冻结的线程,如果没有就是空唤醒,Java是支持的*/

this.notify(); //注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 唤醒所有*/

this.notifyAll(); //注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 当前自己线程 冻结,释放CPU执行资格,释放CPU执行权,CPU就会去执行其他线程了*/

this.wait(); //注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

}

}

正确的示范✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅synchronized (锁🔒== OBJ_LOCK) ,然后是OBJ_LOCK.notify();  使用了同一把OBJ_LOCK锁🔒,是正确的✅

private final Object OBJ_LOCK = newObject();public void testMethod2() throwsInterruptedException {/*** synchronized (OBJ_LOCK) {}

* synchronized的锁🔒是 OBJ_LOCK

* 所以可以:OBJ_LOCK.notify(); OBJ_LOCK.notifyAll(); OBJ_LOCK.wait();*/

synchronized(OBJ_LOCK) {/*** 唤醒 wait(); 冻结的线程,如果没有就是空唤醒,Java是支持的*/OBJ_LOCK.notify();//注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 唤醒所有*/OBJ_LOCK.notifyAll();//注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 当前自己线程 冻结,释放CPU执行资格,释放CPU执行权,CPU就会去执行其他线程了*/OBJ_LOCK.wait();//注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

}

}

代码分析 2   伪代码:

private final Object OBJ_LOCK = newObject();public void testMethod2() throwsInterruptedException {synchronized(OBJ_LOCK🔒锁) {/*** 唤醒 wait(); 冻结的线程,如果没有就是空唤醒,Java是支持的*/OBJ_LOCK🔒锁.notify();//注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 唤醒所有*/OBJ_LOCK🔒锁.notifyAll();//注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

/*** 当前自己线程 冻结,释放CPU执行资格,释放CPU执行权,CPU就会去执行其他线程了*/OBJ_LOCK🔒锁.wait();//注意:⚠️ wait(); notify(); 这些必须要有同步锁包裹着

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值