Java并发:await/waitsleepyield间的区别

是否释放锁:调用sleep和yield的时候不释放当前线程所获得的锁,但是调用await/wait的时候却释放了其获取的锁并阻塞等待。


调用后何时恢复:

# sleep让线程阻塞,且在指定的时间之内都不会执行,时间到了之后恢复到就绪状态,也不一定被立即调度执行;

# yield只是让当前对象回到就绪状态,还是有可能马上被再次被调用执行。

# await/wait,它会一直阻塞在条件队列之上,之后某个线程调用对应的notify/signal方法,才会使得await/wait的线程回到就绪状态,也是不一定立即执行。


谁的方法:yield和sleep方法都是Thread类的,而wait方法是Object类的,await方法是Condition显示条件队列的。


执行环境:yield和sleep方法可以放在线程中的任意位置,而await/wait方法必须放在同步块里面,否则会产生运行时异常。


await/wait

Sleep

Yield

是否释放持有的锁

释放

不释放

不释放

调用后何时恢复

唤醒后进入就绪态

指定时间后

立刻进入就绪态

谁的方法

Condition/Object

Thread

Thread

执行环境

同步代码块

任意位置

任意位置

 

实验

/**
 *
 */
package com.b510.test;
/**
中的sleep()和wait()的区别
 *@author Hongten
 *@date 2013-12-10
 */
public class TestD {
   public static void main(String[] args) {
       new Thread(new Thread1()).start();
       try {
           Thread.sleep(5000);
       } catch (Exception e) {
           e.printStackTrace();
       }
       new Thread(new Thread2()).start();
    }
   
   private static class Thread1 implements Runnable{
       @Override
       public void run(){
           synchronized (TestD.class) {
           System.out.println("enter thread1...");   
           System.out.println("thread1 is waiting...");
           try {

调用wait()方法,线程会放弃对象锁,进入等待此对象的等待锁定池

        

TestD.class.wait();
           } catch (Exception e) {
                e.printStackTrace();
           }
           System.out.println("thread1 is going on ....");
           System.out.println("thread1 is over!!!");
           }
       }
    }
   
   private static class Thread2 implements Runnable{
       @Override
       public void run(){
           synchronized (TestD.class) {
                System.out.println("enterthread2....");
               System.out.println("thread2 is sleep....");

只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

TestD.class.notify();
                //==================

区别

如果我们把代码:TestD.class.notify();给注释掉,即TestD.class调用了wait()方法,但是没有调用notify()

方法,则线程永远处于挂起状态。

                try {

方法导致了程序暂停执行指定的时间,让出cpu该其他线程,

但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

在调用sleep()方法的过程中,线程不会释放对象锁。

           

Thread.sleep(5000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
               System.out.println("thread2 isgoing on....");
               System.out.println("thread2 is over!!!");
           }
       }
    }
}

运行效果:

enter thread1...
thread1 is waiting...
enter thread2....
thread2 is sleep....
thread2 is going on....
thread2 is over!!!
thread1 is going on ....
thread1 is over!!!

如果注释掉代码:

TestD.class.notify();

运行效果:

enter thread1...
thread1 is waiting...
enter thread2....
thread2 is sleep....
thread2 is going on....
thread2 is over!!!

且程序一直处于挂起状态。



https://blog.51cto.com/90sirdb/1914216