当前位置:网站首页>Use and principle of wait notify
Use and principle of wait notify
2022-07-01 05:09:00 【People below two meters are mortals】
List of articles
1、API Introduce
- obj.wait() Let in object Monitor thread to waitSet wait for
- obj.wait(long timeout) Let in object Monitor thread to waitSet wait for , But there will be a time limit , No unlimited waiting
- obj.notify() stay object It's going on waitSet Pick one of the waiting threads to wake up
- obj.notifyAll() Give Way object It's going on waitSet All the waiting threads wake up
They are all means of collaboration between threads , All belong to Object Object method . You must get the lock for this object ( Become Owner), To call these methods
such as :
private final static Object OBJ = new Object();
@SneakyThrows
public static void main(String[] args) {
OBJ.wait();
}

The monitor status that reports an error is abnormal , That is, the current thread has not obtained OBJ lock , perform wait I don't know where to go WaitSet? It should be used in this way
private final static Object OBJ = new Object();
@SneakyThrows
public static void main(String[] args) {
synchronized (OBJ) {
OBJ.wait();
}
}
Example
private final static Object OBJ = new Object();
@SneakyThrows
public static void main(String[] args) {
new Thread(() -> {
synchronized (OBJ) {
log.info(" perform ....");
try {
OBJ.wait(); // Let the thread in OBJ Keep waiting on
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("t1 Other code ....");
}
}, "t1").start();
new Thread(() -> {
synchronized (OBJ) {
log.info(" perform ....");
try {
OBJ.wait(); // Let the thread in OBJ Keep waiting on
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("t2 Other code ....");
}
}, "t2").start();
// The main thread executes in two seconds
TimeUnit.SECONDS.sleep(2);
log.info(" Wake up the OBJ On other threads ");
synchronized (OBJ) {
OBJ.notify(); // Wake up the OBJ Last thread
}
}

You can find ,notify You can only wake up at a time WaitSet The random one in , If necessary t1 and t2 Wake up at the same time , have access to notiyAll, Will all WaitSet The threads in all wake up
2、 principle
Review the following diagram

- Owner Thread discovery condition not met , call wait Method , You can enter WaitSet Turn into WAITING state
- BLOCKED and WAITING All threads are blocked , Not occupy CPU Time slice
- BLOCKED Thread will be Owner Wake up when thread releases lock
- WAITING Thread will be Owner Thread calls notify or notifyAll Wake up when , But waking up doesn't mean the person gets the lock immediately , Still need to enter EntryList Re compete
3、wait and sleep The difference between
- sleep yes Thread Method , and wait yes Object Methods
- sleep There's no need to force and synchronized In combination with , but wait Need and synchronized Together with
- sleep While sleeping , Object locks will not be released , but wait The object lock is released while waiting
- Their states are TIMED_WAITING
4、 Use posture correctly
Here we simulate a scene , Now there is a studio ( lock ), There is a man, Xiao Nan , He has a lot of problems , It must have smoke to work , Let's make it happen
static final Object ROOM = new Object();
static boolean hasCigarette = false;
@SneakyThrows
public static void main(String[] args) {
new Thread(() -> {
synchronized (ROOM) {
log.info(" Do you have any cigarettes ?[{}]", hasCigarette);
if (!hasCigarette) {
log.info(" No smoke , Take a break !");
try {
ROOM.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.info(" Do you have any cigarettes ?[{}]", hasCigarette);
if (hasCigarette) {
log.info(" You can start working ");
}
}
}, " Xiaonan ").start();
for (int i = 0; i < 5; i++) {
new Thread(() -> {
synchronized (ROOM) {
log.info(" You can start working ");
}
}, " Other people ").start();
}
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
synchronized (ROOM) {
ROOM.notify();
hasCigarette = true;
log.info(" Here comes the smoke !");
}
}, " The cigarette man ").start();
}

But there is still a problem with the current program , If there are other threads wait What shall I do? ? It is not easy to wake up the wrong thread ( spurious wakeup )? such as , Now there is another man named little girl , She's strange, too , Only when the takeout arrives can he work
static final Object ROOM = new Object();
static boolean hasCigarette = false;
static boolean hasTakeout = false;
@SneakyThrows
public static void main(String[] args) {
new Thread(() -> {
synchronized (ROOM) {
log.info(" Do you have any cigarettes ?[{}]", hasCigarette);
if (!hasCigarette) {
log.info(" No smoke , Take a break !");
try {
ROOM.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.info(" Do you have any cigarettes ?[{}]", hasCigarette);
if (hasCigarette) {
log.info(" You can start working ");
} else {
log.info(" Didn't do it ...");
}
}
}, " Xiaonan ").start();
new Thread(() -> {
synchronized (ROOM) {
Thread thread = Thread.currentThread();
log.info(" Did the takeout arrive ?[{}]", hasTakeout);
if (!hasTakeout) {
log.info(" No takeout , Take a break !");
try {
ROOM.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.info(" Did the takeout arrive ?[{}]", hasTakeout);
if (hasTakeout) {
log.info(" You can start working ");
} else {
log.info(" Didn't do it ...");
}
}
}, " Little girl ").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
synchronized (ROOM) {
hasTakeout = true;
log.info(" Here's the takeout !");
ROOM.notify();
}
}, " Take away delivery ").start();
}

In order to solve the false awakening , As a result, the correct thread is not awakened , We can try it notifyAll , In this way, the correct target thread must be awakened , But it will also wake up the threads that should not be awakened , So at this time , We can try it while Loop to determine whether it is an effective wake-up , Otherwise again wait
static final Object ROOM = new Object();
static boolean hasCigarette = false;
static boolean hasTakeout = false;
@SneakyThrows
public static void main(String[] args) {
new Thread(() -> {
synchronized (ROOM) {
log.info(" Do you have any cigarettes ?[{}]", hasCigarette);
while (!hasCigarette) {
log.info(" No smoke , Take a break !");
try {
ROOM.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.info(" Do you have any cigarettes ?[{}]", hasCigarette);
if (hasCigarette) {
log.info(" You can start working ");
} else {
log.info(" Didn't do it ...");
}
}
}, " Xiaonan ").start();
new Thread(() -> {
synchronized (ROOM) {
log.info(" Did the takeout arrive ?[{}]", hasTakeout);
while (!hasTakeout) {
log.info(" No takeout , Take a break !");
try {
ROOM.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.info(" Did the takeout arrive ?[{}]", hasTakeout);
if (hasTakeout) {
log.info(" You can start working ");
} else {
log.info(" Didn't do it ...");
}
}
}, " Little girl ").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
synchronized (ROOM) {
hasTakeout = true;
log.info(" Here's the takeout !");
ROOM.notifyAll();
}
}, " Take away delivery ").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
synchronized (ROOM) {
ROOM.notify();
hasCigarette = true;
log.info(" Here comes the smoke !");
}
}, " The cigarette man ").start();
}

So the correct use of templates should be
synchronized(lock) {
while( Conditions not established ) {
lock.wait();
}
// work
}
// Another thread
synchronized(lock) {
lock.notifyAll();
}
边栏推荐
- Leetcode522- longest special sequence ii- hash table - String - double pointer
- FileOutPutStream
- HCIP Day13
- Spanner 论文小结
- 导电滑环使用的注意事项
- [daily question in summer] Luogu p1568 race
- 1076 Forwards on Weibo
- Global and Chinese markets for business weather forecasting 2022-2028: Research Report on technology, participants, trends, market size and share
- Neural network - nonlinear activation
- 打印流与System.setout();
猜你喜欢

Distributed transactions - Solutions

导电滑环短路的原因以及应对措施

分布式-总结列表

Detailed explanation of distributed global unique ID solution

el-cascader回显失败;el-cascader回显不出来

解决:拖动xib控件到代码文件中,报错setValue:forUndefinedKey:this class is not key value coding-compliant for the key

C# wpf 使用DockPanel实现截屏框

CockroachDB 分布式事务源码分析之 TxnCoordSender

LevelDB源码分析之memtable

How to use common datasets in pytorch
随机推荐
JS to solve the problem of floating point multiplication precision loss
STM32 expansion board digital tube display
Vérification simple de la lecture et de l'écriture de qdatastream
Pytoch (II) -- activation function, loss function and its gradient
轻松上手Fluentd,结合 Rainbond 插件市场,日志收集更快捷
LevelDB源码分析之memtable
使用 Nocalhost 开发 Rainbond 上的微服务应用
Rust基础入门之变量绑定与解构
Software intelligence: the "world" and "boundary" of AI sentient beings in AAAs system
CockroachDB 分布式事务源码分析之 TxnCoordSender
Global and Chinese market of 3D CAD 2022-2028: Research Report on technology, participants, trends, market size and share
Simple read / write verification of qdatastream
RuntimeError: “max_pool2d“ not implemented for ‘Long‘
LeetCode_ 53 (maximum subarray and)
Solution: thread 1:[< *> setvalue:forundefined key]: this class is not key value coding compliant for the key*
Data loading and preprocessing
[daily question in summer] first time, second time, deal!
Global and Chinese markets of Ethernet communication modules 2022-2028: Research Report on technology, participants, trends, market size and share
线程安全问题
【暑期每日一題】洛穀 P1568 賽跑