wait()¬ify() for multi-threading

1) sleep is a method of the thread class (Thread), which causes the thread to suspend execution for a specified time, giving execution opportunities to other threads, but the monitoring state is still maintained, and it will automatically resume after that time. Calling sleep does not release the object lock.
wait is a method of the Object class. Calling the wait method on this object causes the thread to give up the object lock and enter the waiting lock pool waiting for this object. Only after the notify method (or notifyAll) is issued for this object, the thread enters the object lock pool to prepare to acquire The object lock enters the running state.

1. These two methods come from different classes: Thread and Object
. 2. The most important thing is that the sleep method does not release the lock, while the wait method releases the lock, so that other threads can use the synchronization control block or method.
3. wait, notify and notifyAll can only be used in synchronization control methods or synchronization control blocks, while sleep can be used anywhere (the scope of use)

  1. synchronized(x){
  2.   x.notify()
  3.   //or wait()
  4.   }
 

4. Sleep must catch exceptions, while wait, notify and notifyAll do not need to catch exceptions

The sleep method belongs to the method in the Thread class, which means that a thread is put into sleep state. After waiting for a certain period of time, it will automatically wake up and enter the runnable state, and will not enter the running state immediately, because the thread scheduling mechanism also takes time to restore the running of the thread. After a thread object calls the sleep method, it will not release all the object locks it holds, so it will not affect the operation of other process objects. But in the process of sleep, its interrupt() may be called by other objects, resulting in InterruptedException. If your program does not catch this exception, the thread will terminate abnormally and enter the TERMINATED state. If your program catches this exception, then the program will continue to execute the catch block (and possibly the finally block) and subsequent code.

Note that the sleep() method is a static method, which means that it is only valid for the current object. For example, t is a thread. By specifying t.sleep() to let the t object enter sleep, this approach is wrong, it will only be make the current thread sleep instead of t thread

wait is a member method of Object. Once an object calls the wait method, the notify() and notifyAll() methods must be used to wake up the process; if the thread owns the synchronization lock of one or some objects, then after calling wait() After that, the thread will release all synchronization resources it holds, not limited to the object on which the wait() method was called. The wait() method will also be generated by other objects calling the interrupt() method during the wait process.

 

 

2) Wait() and notify(): Wait if the condition is not met. When a condition is met, the thread waiting for that condition will be woken up. Generally used in the synchronized mechanism.

For example: thread A

   synchronized(obj) {

               while(!condition) {

                         obj.wait();

                 }

                obj.doSomething();

.....

  }

当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait()。在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A。

线程B

      synchronized(obj) {

              condition = true;

              obj.notify();

        }

需要注意的概念是:  

   1.调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {……} 代码段内(或synchronized方法中)。  

   2.调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {……} 代码段内唤醒A.  

   3.当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。  

   4.如果A1,A2,A3都obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。  

   5.obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。

   6.当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。

 

3)为什么wait(),notify()方法要和synchronized一起使用?

因为wait()方法是通知当前线程等待并释放对象锁,notify()方法是通知等待此对象锁的线程重新获得对象锁,然而,如果没有获得对象锁,wait方法和notify方法都是没有意义的,即必须先获得对象锁,才能对对象锁进行操作,于是,才必须把notify和wait方法写到synchronized方法或是synchronized代码块中了。

以下是demo:

public class ThreadB implements Runnable{
	
	 int total;  
	    public void run()  
	    {  
	        synchronized (this)  
	        {  
	            for (int i = 0; i < 5; i++)  //Thread-0执行完后是10
	            {  
	                total += i;  
	                System.out.println("total is " + total);  
	            }
	            if(total < 15){
	            	try {
	            		System.out.println(Thread.currentThread().getName() + "进入等待状态");
						this.wait();//Thread-0释放锁,Thread-1获取锁
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
	            } else {
	            	System.out.println(Thread.currentThread().getName() + "After execution, wake up Thread-0 to continue execution");
	            	notify();
	            }
	            System.out.println(Thread.currentThread().getName() + "Completed!");
	        }
	        
	    }  
	
	    public static void main(String[] args) {
		        ThreadB b = new ThreadB();  
		        Thread t1  = new Thread(b);
		        Thread t2  = new Thread(b);
		        t1.start();
		        t2.start();
		}
}

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327004508&siteId=291194637