您的位置:首页 > 大数据 > 人工智能

sleep和wait有什么区别?

2016-11-01 15:44 357 查看
参考资料:https://zhidao.baidu.com/question/500790031.html
http://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html http://www.cnphp6.com/archives/62258 http://blog.csdn.net/liuzhenwen/article/details/4202967
1、区别

<span style="font-size:18px;">①、这sleep和wait两个方法来自不同的类分别是Thread和Object
②、wait只能在有线程锁的部分调用,而sleep不需要。
③、wait是睡眠时放开线程锁,而sleep睡眠时占着线程锁。
④、wait需要notify方法来唤醒,而sleep是用时间指定来使他自动醒过来,如果时间不到只能调用interreput()来强行打断。
⑤、sleep方法没有释放同步锁,而wait方法释放了同步锁,使得其他线程可以使用同步控制块或者方法。
⑥、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
⑦、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)
  synchronized(x){
  x.notify()
  //或者wait()
  }</span>

另一种解释:
<span style="font-size:18px;">sleep是你困了,要睡觉,等你睡醒了再干活。
wait是你现在没事做,先眯会儿吧,什么时候领导提醒你该干活了再干。</span>


2、

package com.py.sleep_wait;

public class Test {

public static void main(String[] args) {
new Thread(new Thread1()).start();
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
new Thread(new Thread2()).start();

}

private static class Thread1 implements Runnable {
@Override
public void run() {
synchronized (Test.class) {
System.out.println(System.currentTimeMillis()+",enter thread1...");
System.out.println(System.currentTimeMillis()+",thread1 is waiting...");
try {
// 调用wait()方法,线程会放弃对象锁,进入等待此对象的等待锁定池
Test.class.wait();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis()+",thread1 is going on ....");

System.out.println(System.currentTimeMillis()+",thread1 is over!!!");
}
}
}

private static class Thread2 implements Runnable {
@Override
public void run() {
synchronized (Test.class) {
System.out.println(System.currentTimeMillis()+",enter thread2....");
System.out.println(System.currentTimeMillis()+",thread2 is sleep....");
// 只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
/* 如果我们把代码:Test.class.notify();给注释掉,即Test.class调用了wait()方法,但是没有调用notify()
方法,则线程永远处于挂起状态。
*/
Test.class.notify();
try {
// sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,
// 但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
// 在调用sleep()方法的过程中,线程不会释放对象锁。
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis()+",thread2 is going on....");
System.out.println(System.currentTimeMillis()+",thread2 is over!!!");
}
}
}

}

控制台输出:

1477982883412,enter thread1...
1477982883412,thread1 is waiting...
1477982886423,enter thread2....
1477982886423,thread2 is sleep....
1477982889423,thread2 is going on....
1477982889423,thread2 is over!!!
1477982889423,thread1 is going on ....
1477982889423,thread1 is over!!!

3、java中wait、notify、notifyAll

这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。
如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。

其中wait方法有三个over load方法:
wait()
wait(long)
wait(long,int)
wait方法通过参数可以指定等待的时长。如果没有指定参数,默认一直等待直到被通知。

注意:

任何一个时刻,对象的控制权(monitor)只能被一个线程拥有。
无论是执行对象的wait、notify还是notifyAll方法,必须保证当前运行的线程取得了该对象的控制权(monitor)
如果在没有控制权的线程里执行对象的以上三种方法,就会报java.lang.IllegalMonitorStateException异常。
JVM基于多线程,默认情况下不能保证运行时线程的时序性

线程取得控制权的方法:

  
 ①执行对象的某个同步实例方法。
②执行对象对应类的同步静态方法。
③执行对该对象加同步锁的同步块。
4、package com.py.sleep_wait;

/**
* NotifyThread是用来模拟3秒钟后通知其他等待状态的线程的线程类;
* WaitThread是用来模拟等待的线程类;
* 等待的中间对象是flag,一个String[]对象;
* main方法中同时启动一个Notify线程和三个wait线程;
*/
public class NotifyTest {

private String flag[] = {"true"};

public static void main(String[] args) throws InterruptedException {
System.out.println("Main Thread Run!");
NotifyTest test = new NotifyTest();
NotifyThread notifyThread =test.new NotifyThread("notify01");
WaitThread waitThread01 = test.new WaitThread("waiter01");
WaitThread waitThread02 = test.new WaitThread("waiter02");
WaitThread waitThread03 = test.new WaitThread("waiter03");
notifyThread.start();
waitThread01.start();
waitThread02.start();
waitThread03.start();
}

class NotifyThread extends Thread{
public NotifyThread(String name) {
super(name);
}
public void run() {
try {
sleep(3000);//推迟3秒钟通知
} catch (InterruptedException e) {
e.printStackTrace();
}
// 执行对该对象加同步锁的同步块来取得了该对象的控制权(monitor)
synchronized (flag) {
flag[0] = "false";
// flag.notify();
// flag.notify();
// flag.notify();
//或者写三句flag.notify();才能把三个wait唤醒,不然程序将一直wait
flag.notifyAll();
}
}
};

class WaitThread extends Thread {
public WaitThread(String name) {
super(name);
}

public void run() {
// 执行对该对象加同步锁的同步块来取得了该对象的控制权(monitor)
synchronized (flag) {
while (flag[0]!="false") {
System.out.println(getName() + " begin waiting!");
long waitTime = System.currentTimeMillis();
try {
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
waitTime = System.currentTimeMillis() - waitTime;
System.out.println("wait time :"+waitTime);
}
System.out.println(getName() + " end waiting!");
}
}

}

}

控制台输出:

Main Thread Run!
waiter01 begin waiting!
waiter02 begin waiting!
waiter03 begin waiting!
wait time :3009
waiter03 end waiting!
wait time :3009
waiter02 end waiting!
wait time :3009
waiter01 end waiting!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息