Java并发:await/waitsleepyield间的区别

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

 

调用后何时恢复:

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

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

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

 

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

 

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


await/wait

Sleep

Yield

是否释放持有的锁

释放

不释放

不释放

调用后何时恢复

唤醒后进入就绪态

指定时间后

立刻进入就绪态

谁的方法

Condition/Object

Thread

Thread

执行环境

同步代码块

任意位置

任意位置

 

实验

/**

 *

 */

package com.b510.test;

/**

 *java中的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 {

                    //sleep()方法导致了程序暂停执行指定的时间,让出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!!!

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