当前位置:网站首页>Concurrent wait/notify description

Concurrent wait/notify description

2022-06-28 05:16:00 Under the seven kingdoms, I want 99

1 wait/notify Principle

 Insert picture description here

  • 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

2 wait/notify Of API

  • obj.wait() Let in object Monitor thread to waitSet wait for

  • obj.notify() stay object It's going on waitSet Pick one of the waiting threads to wake up **( Random )**

  • 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 , To call these methods

final static Object obj = new Object();
public static void main(String[] args) {
    
 new Thread(() -> {
    
 synchronized (obj) {
    
 log.debug(" perform ....");
 try {
    
     //  Let the thread in obj Keep waiting on 
 obj.wait(); 
 } catch (InterruptedException e) {
    
 e.printStackTrace();
 }
 log.debug(" Other code ....");
 }
 }).start();
 new Thread(() -> {
    
 synchronized (obj) {
    
 log.debug(" perform ....");
 try {
    
     //  Let the thread in obj Keep waiting on 
 obj.wait(); 
 } catch (InterruptedException e) {
    
 e.printStackTrace();
 }
 log.debug(" Other code ....");
 }
 }).start();
 //  The main thread executes in two seconds 
 sleep(2);
 log.debug(" Wake up the  obj  On other threads ");
 synchronized (obj) {
    
     //  Wake up the obj Last thread   First test 
 obj.notify(); 
     //  Wake up the obj All waiting threads on   Second test 
 // obj.notifyAll(); 
 }
}

First test notify result

20:00:53.096 [Thread-0] c.TestWaitNotify -  perform .... 
20:00:53.099 [Thread-1] c.TestWaitNotify -  perform .... 
20:00:55.096 [main] c.TestWaitNotify -  Wake up the  obj  On other threads 
20:00:55.096 [Thread-0] c.TestWaitNotify -  Other code .... 

Second test notifyAll result

19:58:15.457 [Thread-0] c.TestWaitNotify -  perform .... 
19:58:15.460 [Thread-1] c.TestWaitNotify -  perform .... 
19:58:17.456 [main] c.TestWaitNotify -  Wake up the  obj  On other threads 
19:58:17.456 [Thread-1] c.TestWaitNotify -  Other code .... 
19:58:17.456 [Thread-0] c.TestWaitNotify -  Other code .... 

wait() Method releases the lock on the object , Get into WaitSet Waiting area , This allows other threads to get the lock of the object . Wait indefinitely , until notify until .

wait(long n) A time-bound wait , To n End waiting in milliseconds , Or by notify

3 wait/notify Use

sleep(long n) and wait(long n) The difference between

Different :

  • 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

identical :

  • they state TIMED_WAITING

Case study 1

static final Object room = new Object();
static boolean hasCigarette = false;
static boolean hasTakeout = false;

new Thread(() -> {
    
 synchronized (room) {
    
 log.debug(" Do you have any cigarettes ?[{}]", hasCigarette);
 if (!hasCigarette) {
    
 log.debug(" No smoke , Take a break !");
 sleep(2);
 }
 log.debug(" Do you have any cigarettes ?[{}]", hasCigarette);
 if (hasCigarette) {
    
 log.debug(" You can start working ");
 }
 }
}, " Xiaonan ").start();
for (int i = 0; i < 5; i++) {
    
 new Thread(() -> {
    
 synchronized (room) {
    
 log.debug(" You can start working ");
 }
 }, " Other people ").start();
}
sleep(1);
new Thread(() -> {
    
 //  Can you add  synchronized (room)?
 hasCigarette = true;
 log.debug(" Here comes the smoke !");
}, " The cigarette man ").start();

/*  Running results : 20:49:49.883 [ Xiaonan ] c.TestCorrectPosture -  Do you have any cigarettes ?[false] 20:49:49.887 [ Xiaonan ] c.TestCorrectPosture -  No smoke , Take a break ! 20:49:50.882 [ The cigarette man ] c.TestCorrectPosture -  Here comes the smoke ! 20:49:51.887 [ Xiaonan ] c.TestCorrectPosture -  Do you have any cigarettes ?[true] 20:49:51.887 [ Xiaonan ] c.TestCorrectPosture -  You can start working  20:49:51.887 [ Other people ] c.TestCorrectPosture -  You can start working  20:49:51.887 [ Other people ] c.TestCorrectPosture -  You can start working  20:49:51.888 [ Other people ] c.TestCorrectPosture -  You can start working  20:49:51.888 [ Other people ] c.TestCorrectPosture -  You can start working  20:49:51.888 [ Other people ] c.TestCorrectPosture -  You can start working  */

explain :

  • Other working threads , All the time , Efficiency is too low
  • Xiaonan thread must get enough sleep 2s And then wake up , Even if the cigarettes are delivered in advance , I can't wake up right now
  • added synchronized (room) after , It's like Xiao Nan sleeping inside with the door locked , There's no way cigarettes can get through the door ,main No addition synchronized It's like main The thread came in through the window
  • resolvent , Use wait - notify Mechanism

Case study 2

new Thread(() -> {
    
 synchronized (room) {
    
 log.debug(" Do you have any cigarettes ?[{}]", hasCigarette);
 if (!hasCigarette) {
    
 log.debug(" No smoke , Take a break !");
 try {
    
 room.wait(2000);
 } catch (InterruptedException e) {
    
 e.printStackTrace();
 }
 }
 log.debug(" Do you have any cigarettes ?[{}]", hasCigarette);
 if (hasCigarette) {
    
 log.debug(" You can start working ");
 }
 }
}, " Xiaonan ").start();
for (int i = 0; i < 5; i++) {
    
 new Thread(() -> {
    
 synchronized (room) {
    
 log.debug(" You can start working ");
 }
 }, " Other people ").start();
}
sleep(1);
new Thread(() -> {
    
 synchronized (room) {
    
 hasCigarette = true;
 log.debug(" Here comes the smoke !");
 room.notify();
 }
}, " The cigarette man ").start();
/*  Running results : 20:51:42.489 [ Xiaonan ] c.TestCorrectPosture -  Do you have any cigarettes ?[false] 20:51:42.493 [ Xiaonan ] c.TestCorrectPosture -  No smoke , Take a break ! 20:51:42.493 [ Other people ] c.TestCorrectPosture -  You can start working  20:51:42.493 [ Other people ] c.TestCorrectPosture -  You can start working  20:51:42.494 [ Other people ] c.TestCorrectPosture -  You can start working  20:51:42.494 [ Other people ] c.TestCorrectPosture -  You can start working  20:51:42.494 [ Other people ] c.TestCorrectPosture -  You can start working  20:51:43.490 [ The cigarette man ] c.TestCorrectPosture -  Here comes the smoke ! 20:51:43.490 [ Xiaonan ] c.TestCorrectPosture -  Do you have any cigarettes ?[true] 20:51:43.490 [ Xiaonan ] c.TestCorrectPosture -  You can start working  */

explain :

  • It solves the problem of thread blocking of other working threads

Existing problems , That is, there are scenarios where other threads are waiting , There is no guarantee that the specified thread will wake up .

Case study 3

new Thread(() -> {
    
 synchronized (room) {
    
 log.debug(" Do you have any cigarettes ?[{}]", hasCigarette);
 if (!hasCigarette) {
    
 log.debug(" No smoke , Take a break !");
 try {
    
 room.wait();
 } catch (InterruptedException e) {
    
 e.printStackTrace();
 }
 }
 log.debug(" Do you have any cigarettes ?[{}]", hasCigarette);
 if (hasCigarette) {
    
 log.debug(" You can start working ");
 } else {
    
 log.debug(" Didn't do it ...");
 }
 }
}, " Xiaonan ").start();
new Thread(() -> {
    
 synchronized (room) {
    
 Thread thread = Thread.currentThread();
 log.debug(" Did the takeout arrive ?[{}]", hasTakeout);
 if (!hasTakeout) {
    
 log.debug(" No takeout , Take a break !");
 try {
    
 room.wait();
 } catch (InterruptedException e) {
    
 e.printStackTrace();
 }
 }
 log.debug(" Did the takeout arrive ?[{}]", hasTakeout);
 if (hasTakeout) {
    
 log.debug(" You can start working ");
 } else {
    
 log.debug(" Didn't do it ...");
 }
 }
}, " Little girl ").start();
sleep(1);
new Thread(() -> {
    
 synchronized (room) {
    
 hasTakeout = true;
 log.debug(" Here's the takeout !");
 room.notify();
 }
}, " Take away delivery ").start();
/*  Running results : 20:53:12.173 [ Xiaonan ] c.TestCorrectPosture -  Do you have any cigarettes ?[false] 20:53:12.176 [ Xiaonan ] c.TestCorrectPosture -  No smoke , Take a break ! 20:53:12.176 [ Little girl ] c.TestCorrectPosture -  Did the takeout arrive ?[false] 20:53:12.176 [ Little girl ] c.TestCorrectPosture -  No takeout , Take a break ! 20:53:13.174 [ Take away delivery ] c.TestCorrectPosture -  Here's the takeout ! 20:53:13.174 [ Xiaonan ] c.TestCorrectPosture -  Do you have any cigarettes ?[false] 20:53:13.174 [ Xiaonan ] c.TestCorrectPosture -  Didn't do it ... */

explain :

  • notify Only one can wake up randomly WaitSet Thread in , At this time, if there are other threads waiting , Then you may not wake up the right line cheng , be called spurious wakeup

resolvent : notifyAll Wake up all threads

Case study 4

new Thread(() -> {
    
 synchronized (room) {
    
 hasTakeout = true;
 log.debug(" Here's the takeout !");
 room.notifyAll();
 }
}, " Take away delivery ").start();
/* 20:55:23.978 [ Xiaonan ] c.TestCorrectPosture -  Do you have any cigarettes ?[false] 20:55:23.982 [ Xiaonan ] c.TestCorrectPosture -  No smoke , Take a break ! 20:55:23.982 [ Little girl ] c.TestCorrectPosture -  Did the takeout arrive ?[false] 20:55:23.982 [ Little girl ] c.TestCorrectPosture -  No takeout , Take a break ! 20:55:24.979 [ Take away delivery ] c.TestCorrectPosture -  Here's the takeout ! 20:55:24.979 [ Little girl ] c.TestCorrectPosture -  Did the takeout arrive ?[true] 20:55:24.980 [ Little girl ] c.TestCorrectPosture -  You can start working  20:55:24.980 [ Xiaonan ] c.TestCorrectPosture -  Do you have any cigarettes ?[false] 20:55:24.980 [ Xiaonan ] c.TestCorrectPosture -  Didn't do it ... */

explain :

  • use notifyAll Only solve the wake-up problem of a thread , But use if + wait There is only one chance to judge , Once the conditions are not established , There is no new A chance to judge

solve : use while + wait, When conditions don't hold , Again wait

Case study 5

if (!hasCigarette) {
    
 log.debug(" No smoke , Take a break !");
 try {
    
 room.wait();
 } catch (InterruptedException e) {
    
 e.printStackTrace();
 }
}

//  Change it to 

while (!hasCigarette) {
    
 log.debug(" No smoke , Take a break !");
 try {
    
 room.wait();
 } catch (InterruptedException e) {
    
 e.printStackTrace();
 }
}
/*  Running results : 20:58:34.322 [ Xiaonan ] c.TestCorrectPosture -  Do you have any cigarettes ?[false] 20:58:34.326 [ Xiaonan ] c.TestCorrectPosture -  No smoke , Take a break ! 20:58:34.326 [ Little girl ] c.TestCorrectPosture -  Did the takeout arrive ?[false] 20:58:34.326 [ Little girl ] c.TestCorrectPosture -  No takeout , Take a break ! 20:58:35.323 [ Take away delivery ] c.TestCorrectPosture -  Here's the takeout ! 20:58:35.324 [ Little girl ] c.TestCorrectPosture -  Did the takeout arrive ?[true] 20:58:35.324 [ Little girl ] c.TestCorrectPosture -  You can start working  20:58:35.324 [ Xiaonan ] c.TestCorrectPosture -  No smoke , Take a break ! */

Structural mode :

synchronized(lock) {
    
 while( Conditions not established ) {
    
 lock.wait();
 }
 //  work 
}
// Another thread 
synchronized(lock) {
    
 lock.notifyAll();
}
原网站

版权声明
本文为[Under the seven kingdoms, I want 99]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/179/202206280429199404.html