当前位置:网站首页>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();
}
边栏推荐
- 缓冲流与转换流
- 使用 Nocalhost 开发 Rainbond 上的微服务应用
- LeetCode_ 28 (implement strstr())
- LeetCode_ 35 (search insertion position)
- Global and Chinese market of mainboard 2022-2028: Research Report on technology, participants, trends, market size and share
- How to start learning editing? Detailed analysis of zero basis
- Programmers dig "holes" to get rich: if they find a loophole, they will be rewarded 12.72 million yuan
- el-form表单新增表单项动态校验;el-form校验动态表单v-if不生效;
- FileInputStream
- 导电滑环使用的注意事项
猜你喜欢

Leetcode316- remove duplicate letters - stack - greedy - string

Leetcode1497- check whether array pairs can be divided by K - array - hash table - count

RuntimeError: mean(): input dtype should be either floating point or complex dtypes. Got Long instead

LeetCode522-最长特殊序列II-哈希表-字符串-双指针

C# wpf 使用DockPanel实现截屏框

LevelDB源码分析之memtable

手动实现一个简单的栈

0xc000007b应用程序无法正常启动解决方案(亲测有效)

How to hide browser network IP address and modify IP internet access?
![解决:Thread 1:[<*>setValue:forUndefinedKey]:this class is not key value coding-compliant for the key *](/img/88/0b99d1db2cdc70ab72d2b3c623dfaa.jpg)
解决:Thread 1:[<*>setValue:forUndefinedKey]:this class is not key value coding-compliant for the key *
随机推荐
0xc000007b应用程序无法正常启动解决方案(亲测有效)
解决:Thread 1:[<*>setValue:forUndefinedKey]:this class is not key value coding-compliant for the key *
RuntimeError: “max_pool2d“ not implemented for ‘Long‘
复制宝贝提示材质不能为空,如何解决?
FileInputStream
点赞的云函数
AcWing 889. 01 sequence satisfying the condition (Cartland number)
el-form表单新增表单项动态校验;el-form校验动态表单v-if不生效;
[summer daily question] Luogu p5886 Hello, 2020!
Pytoch (II) -- activation function, loss function and its gradient
Pytoch (IV) -- visual tool visdom
手动实现一个简单的栈
AssertionError assert I.ndim == 4 and I.shape[1] == 3
Global and Chinese market of enterprise wireless LAN 2022-2028: Research Report on technology, participants, trends, market size and share
[hard ten treasures] - 2 [basic knowledge] characteristics of various topological structures of switching power supply
Sqlplus connects using the instance name
[une question par jour pendant l'été] course luogu p1568
RuntimeError: mean(): input dtype should be either floating point or complex dtypes. Got Long instead
线程类的几大创建方法
打印流与System.setout();