1.简单了解一下wait
wait、sleep:用于线程休眠
wait是Object方法:
有参数时:wait(500)表示Time_waiting状态
无参数:wait()或wait(0)都表示无限等待:waiting状态
Sleep是Thread的静态方法:
Sleep(500)表示Time_waiting状态
Sleep(0)表示当前线程重新触发一次CPU竞争
不存在无参的情况:会报错
wait所做的事情:
1.使当前的线程进行等待
2.释放当前的锁;
3.被唤醒时,重新尝试获取这个锁
wait结束等待的条件 :
1.其他线程(也可以不是线程)调用了该对象的notify或notifyAll方法
2.其他线程(也可以不是线程)调用该等待线程的interrupted方法
3.等待时间超时:wait(有参)
注意:wait(0)表示的是无限等待
2.wait的用法:
1.必须配合synchronized使用
2.且使用的必须为同一个对象:synchronized (A)配合A.wait()使用
3.当线程执行到object.wait()时,此线程会同时释放锁synchronized (object);当它结束了wait后,此线程又会重新去争抢锁synchronized (object)。
public class Wait {
public static void main(String[] args) throws InterruptedException {
Object object=new Object();
Thread thread=new Thread(()->{
synchronized (object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行完成");
}
});
thread.start();
}
}
执行结果:
当前程序中不存在满足wait结束等待的条件,所以永远不会输出“执行完成”
3.wait结束等待:
1.使用notify:
必须配合synchronized使用;
且在notify后,当前线程不会马上释放锁,要等到当前线程被synchronized修饰的代码执行完,才会释放锁;
使用notify的对象为A,则只能唤醒A.wait()的线程,不能唤醒B.wait()的线程;
****小区别:
notify()方法——随机唤醒一个wait的线程
notifyAll()方法——唤醒所有wait的线程,让这些被唤醒的线程去争抢,按争抢顺序依次执行
public class Wait_notify2 {
public static void main(String[] args) {
Object object=new Object();
Thread thread1=new Thread(()->{
synchronized (object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程1执行完成");
});
Thread thread2=new Thread(()->{
synchronized (object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程2执行完成");
});
Thread thread3=new Thread(()->{
synchronized (object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程3执行完成");
});
thread1.start();
thread2.start();
thread3.start();
Thread thread4=new Thread(()->{
synchronized (object){
//使用一次notify只能唤醒一个线程;
//使用一次notifyAll可唤醒所有的线程
object.notify();
object.notifyAll();
System.out.println("线程4去唤醒wait的线程");
}
});
thread4.start();
}
}
输出的结果为:
当使用object.notify()时:只唤醒一个等待线程
当使用object.notifyAll()时:唤醒所有等待的线程
2.使用interrupted
调用该等待线程的interrupted方法,但会抛出异常;然后继续执行wait后的代码
public class Wait_interrupted {
public static void main(String[] args) throws InterruptedException {
Object object=new Object();
Thread thread1=new Thread(()->{
System.out.println("线程1去获得锁");
synchronized (object){
System.out.println("线程1得到了锁");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程1执行完成");
});
thread1.start();
//让主线程休眠一会,让线程1去得到锁并且处于休眠wait
Thread.sleep(500);
System.out.println("使用线程2去打断线程1的wait");
//打断线程1
thread1.interrupt();
}
}
输出的结果为:
3.wait时间超时
当时间超时,会自动恢复执行,会重新去获得锁,然后从wait的下一行开始执行
public class Wait_timeout {
public static void main(String[] args) {
Object object=new Object();
Thread thread1=new Thread(()->{
System.out.println("去获得锁");
synchronized (object){
System.out.println("得到了锁");
try {
object.wait(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程1执行完成");
});
thread1.start();
}
}
执行结果为: