一、sleep和wait方法的区别根本区别:sleep是thread类中的方法,不会马上进入运行状态,wait是object类中的方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyall()方法唤醒该进程
释放同步锁:sleep会释放cpu,但是sleep不会释放同步锁的资源,wait会释放同步锁资源
使用范围: sleep可以在任何地方使用,但wait只能在synchronized的同步方法或是代码块中使用
异常处理: sleep需要捕获异常,而wait不需要捕获异常
二、wait方法使当前执行代码的线程进行等待. (把线程放到等待队列中)
释放当前的锁
满足一定条件时被唤醒, 重新尝试获取这个锁.
wait 要搭配 synchronized 来使用,脱离 synchronized 使用 wait 会直接抛出异常.
wait方法的使用wait方法
/** * wait的使用 */public class waitdemo1 { public static void main(string[] args) { object lock = new object(); thread t1 = new thread(() -> { system.out.println("线程1开始执行"); try { synchronized (lock) { system.out.println("线程1调用wait方法...."); // 无限期的等待状态 lock.wait(); } } catch (interruptedexception e) { e.printstacktrace(); } system.out.println("线程1执行完成"); }, "线程1"); t1.start(); }}
有参wait线程和无参wait线程
/** * 有参wait线程和无参wait线程 */public class waitdemo2 { public static void main(string[] args) { object lock1 = new object(); object lock2 = new object(); thread t1 = new thread(()->{ system.out.println("线程1开始执行"); synchronized (lock1){ try { lock1.wait(); } catch (interruptedexception e) { e.printstacktrace(); } system.out.println("线程1执行完成"); } },"无参wait线程"); t1.start(); thread t2 = new thread(()->{ system.out.println("线程2开始执行"); synchronized (lock2){ try { lock2.wait(60*60*1000); } catch (interruptedexception e) { e.printstacktrace(); } system.out.println("线程2执行完成"); } },"有参wait线程"); t2.start(); }}
wait结束等待的条件①其他线程调用该对象的 notify 方法.
②wait 等待时间超时 (wait 方法提供一个带有 timeout 参数的版本, 来指定等待时间).
③其他线程调用该等待线程的 interrupted 方法, 导致 wait 抛出 interruptedexception 异常
三、notify和notifyall方法notify 方法只是唤醒某一个等待的线程
方法notify()也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁的其它线程
如果有多个线程等待,随机挑选一个wait状态的线程
在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出同步代码块之后才会释放对象锁
notify方法的使用
/** * wait的使用, 如果有多个线程等待,随机挑选一个wait状态的线程 */public class waitnotifydemo { public static void main(string[] args) { object lock1 = new object(); object lock2 = new object(); thread t1 = new thread(()->{ system.out.println("线程1开始执行"); try { synchronized (lock1) { system.out.println("线程1调用wait方法"); lock1.wait(); } } catch (interruptedexception e) { e.printstacktrace(); } system.out.println("线程1执行完成"); },"线程1"); thread t2 = new thread(()->{ system.out.println("线程2开始执行"); try { synchronized (lock1) { system.out.println("线程2调用wait方法"); lock1.wait(); } } catch (interruptedexception e) { e.printstacktrace(); } system.out.println("线程2执行完成"); },"线程2"); t1.start(); t2.start(); // 唤醒 lock1 对象上休眠的线程的(随机唤醒一个) thread t3 = new thread(()->{ try { thread.sleep(1500); } catch (interruptedexception e) { e.printstacktrace(); } system.out.println("线程3开始执行"); synchronized (lock1){ //发出唤醒通知 system.out.println("执行了唤醒"); try { thread.sleep(2000); } catch (interruptedexception e) { e.printstacktrace(); } } },"线程3"); t3.start(); }}
notifyall方法可以一次唤醒所有的等待线程
notifyall方法的使用
/** * notifyall-唤醒所有线程 */public class waitnotifyall { public static void main(string[] args) { object lock = new object(); new thread(() -> { system.out.println("线程1:开始执行"); synchronized (lock) { try { lock.wait(); } catch (interruptedexception e) { e.printstacktrace(); } system.out.println("线程1:执行完成"); } }, "无参wait线程").start(); new thread(() -> { synchronized (lock) { system.out.println("线程2:开始执行 |" + localdatetime.now()); try { lock.wait(60 * 60 * 60 * 1000); } catch (interruptedexception e) { e.printstacktrace(); } system.out.println("线程2:执行完成 | " + localdatetime.now()); } }, "有参wait线程").start(); new thread(() -> { try { timeunit.seconds.sleep(1); } catch (interruptedexception e) { e.printstacktrace(); } synchronized (lock) { system.out.println("唤醒所有线程"); lock.notifyall(); } }).start(); }}
notify和notifyall方法的区别
当你调用notify时,只有一个等待线程会被唤醒而且它不能保证哪个线程会被唤醒,这取决于线程调度器。
调用notifyall方法,那么等待该锁的所有线程都会被唤醒,但是在执行剩余的代码之前,所有被唤醒的线程都将争夺锁定,这就是为什么在循环上调用wait,因为如果多个线程被唤醒,那么线程是将获得锁定将首先执行,它可能会重置等待条件,这将迫使后续线程等待。
因此,notify和notifyall之间的关键区别在于notify()只会唤醒一个线程,而notifyall方法将唤醒所有线程。
以上就是java中sleep和wait方法有什么区别的详细内容。