- What is the waiting notification mechanism
- Waiting for the realization of the notification mechanism
- notify will not release the lock object immediately
- interrupt will interrupt the waiting of the thread
- The difference between notify and notifyAll
- Use of wait (Long)
What is the waiting notification mechanism
Coupon platform https://www.cqfenfa.com/In a single thread, the operation to be executed needs to meet certain conditions before it can be executed. You can put this operation in an if statement block.
In multi-threaded programming, the condition of thread A may not be satisfied but only temporarily. Later other threads B may update the condition so that the condition of thread A is satisfied. Thread A can be suspended until its conditions are met. A thread wake up
Atomic{
while(条件不成立)
{
等待
}
条件满足后,当前线程被唤醒
}
Waiting for the realization of the notification mechanism
The Wait method in the object class can make the current thread's code suspend execution until notified or interrupted
note:
(1) The wait method can only be called by the lock object in the synchronization code block
(2) Call the wait method, the current thread will release the lock
public class Text16_5 {
public static void main(String[] args) throws InterruptedException {
String text="hello";
System.out.println("同步前代码块");
synchronized (text)
{
System.out.println("同步代码块开始");
text.wait();
System.out.println("同步代码块结束");
}
System.out.println("全部结束");
}
}
Because the wait method of the lock object is called, the lock object is released, and it is in a waiting state, and it will wait forever if it is not awakened.
The notify method of the object class can wake up the thread. This method must also be synchronized in the code block. It is called by the lock object. Calling wait/notify without using the lock object will report the IiegalMonuitorStateExeption exception. If there are multiple waiting threads, the notify method can only Wake up one of them. After calling the notify method in the synchronized code block, the lock object will not be released immediately. The lock object will not be released until the current synchronized code block is executed. Generally, notify is placed at the end of the synchronized code block.
synchronized(锁对象)
{
//执行修改保护条件的代码
//唤醒其他线程
锁对象.notify();
}
public class TextNotify {
public static void main(String[] args) throws InterruptedException {
String text="hello";
Thread t1=new Thread(new Runnable() {
@Override
public void run() {
synchronized (text)
{
System.out.println("同步代码块开始");
try {
text.wait();//线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("同步代码块结束");
}
}
});
Thread t2=new Thread(new Runnable() {
@Override
public void run() {
synchronized (text)
{
System.out.println("线程开始唤醒");
text.notify();
System.out.println("线程结束唤醒");
}
}
});
t1.start();//开启t1线程 t1等待
Thread.sleep(3000);//睡眠3秒 确保t1处于等待状态
t2.start();//唤醒t1线程
}
}
notify will not release the lock object immediately
Case:
import java.util.ArrayList;
import java.util.List;
public class NotifyText2 {
public static void main(String[] args) throws InterruptedException {
List<String> strings=new ArrayList<>();
Thread t1=new Thread(new Runnable() {
@Override
public void run() {
synchronized (strings)
{
System.out.println("线程1开始等待");
try {
strings.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1被唤醒");
}
}
});
Thread t2=new Thread(new Runnable() {
@Override
public void run() {
synchronized (strings)
{
for (int i = 0; i <10 ; i++) {
strings.add("data"+i);
System.out.println("线程2添加了"+(i+1));
if(strings.size()==5)
{
strings.notify();
System.out.println("线程2被唤醒");
}
}
}
}
});
t1.start();
Thread.sleep(1000);
t2.start();
}
}
The code of thread 2 has not been executed yet, and the lock is still being executed without being released immediately. You need to wait until all code blocks are executed before releasing it.
interrupt will interrupt the waiting of the thread
public class InterruptText {
private static final String name=new String();
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(new Runnable() {
@Override
public void run() {
synchronized (name)
{
try {
System.out.println("同步代码块开始");
name.wait();
System.out.println("同步代码块结束");
} catch (InterruptedException e) {
System.out.println("wait被中断"+e);
}
}
}
});
t1.start();
Thread.sleep(2000);
t1.interrupt();
}
}
It turns out that the lock object needs to execute the synchronization code block to release the lock object. If an exception is encountered during the execution process, the thread will be terminated and the lock object will be released. Calling the wait method will also release the lock object.
The difference between notify and notifyAll
Notify can only wake up one at a time. If multiple threads are waiting, only one of them can be awakened randomly. To wake up all waiting threads, notifyAll needs to be called.
public class InterruptText {
private static final String name=new String();
public static void main(String[] args) throws InterruptedException {
String str=new String();
NotifyAll notifyAll=new NotifyAll(str);
NotifyAll notifyAl2=new NotifyAll(str);
NotifyAll notifyAll3=new NotifyAll(str);
notifyAll.setName("线程一");
notifyAl2.setName("线程二");
notifyAll3.setName("线程三");
notifyAll.start();
notifyAl2.start();
notifyAll3.start();
Thread.sleep(2000);//休眠两秒
synchronized (str)
{
//str.notify();只能随机唤醒一个
str.notifyAll();//唤醒全部线程
}
};
static class NotifyAll extends Thread
{
private String name;
private NotifyAll(String name)
{
this.name=name;
}
@Override
public void run() {
synchronized (name)
{
try {
System.out.println(Thread.currentThread().getName()+"同步代码块开始");
name.wait();
System.out.println(Thread.currentThread().getName()+"同步代码块结束");
} catch (InterruptedException e) {
System.out.println("wait被中断"+e);
}
}
}
}
}
If the evil of calling notify() only once can wake up one of the threads, the other waiting threads are still in the waiting state, and the notification signal is missed. This phenomenon is called signal loss.
Use of wait (Long)
Wait (Long) method with parameters, no operation within a specified time will be automatically awakened