目录
1.wait()和wait(long timeout)
1.wait的作用
1.使当前执行代码的线程进行等待。(把线程放在等待队列中)
2.释放当前锁(这需要调用wait的线程是加锁状态,这里的释放是指先暂停对Synchronized所修饰的代码块的 运行,后续在重新获取锁的占有权后继续执行wait代码后面的部分)。
3.满足一定条件时,让使用wait的线程被唤醒(其他线程中调用notify/notifyAll,或者代码抛出
InterruptedException,线程宕掉等),需要重新获取这个锁(需要参与锁竞争)。
public final void wait() throws InterruptedException {
wait(0);
}
wati(0)的作用是释放锁,并一直休眠
wait(1000)的作用是释放锁,1000ms后重新竞争锁
2.示例说明
package com.source.object;
/**
* @author dongguanghui
* @date 2024/1/19 16:05
*/
public class Wait1 {
public static void main(String[] args) {
Object object = new Object();
Thread thread0 = new Thread(() -> {
synchronized (object) {
System.out.println("0抢到锁");
try {
System.out.println("0释放锁");
object.wait(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("0执行完");
}
});
Thread thread1 = new Thread(() -> {
synchronized (object) {
System.out.println("1抢到锁");
try {
Thread.sleep(2000);
System.out.println("1释放锁");
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1执行完");
}
});
thread0.start();
thread1.start();
}
}
以上代码有两种可能的结果
1.thread0先抢到锁
0释放锁后,等待3秒后再去抢锁,继续执行直到完成
1抢到锁后,2秒后释放锁,一直休眠
0抢到锁
0释放锁
1抢到锁
1释放锁
0执行完
2.thread1先抢到锁
1抢到锁后,2秒后释放锁,一直休眠
0抢到锁后,释放锁,等待3秒后再去抢锁,继续执行直到完成
1抢到锁
1释放锁
0抢到锁
0释放锁
0执行完
2.notify()
notify()表示随机唤醒一个休眠中的锁
package com.source.object;
/**
* @author dongguanghui
* @date 2024/1/19 16:53
*/
public class Wait2 {
public static void main(String[] args) {
Object object = new Object();
Thread thread0 = new Thread(() -> {
synchronized (object) {
System.out.println("0抢到锁");
try {
System.out.println("0释放锁");
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("0执行完");
}
});
Thread thread1 = new Thread(() -> {
synchronized (object) {
System.out.println("1抢到锁");
try {
System.out.println("1释放锁");
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1执行完");
}
});
Thread thread2 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (object) {
object.notify();
System.out.println("唤醒完成");
}
});
thread0.start();
thread1.start();
thread2.start();
}
}
以上代码有两种结果
1.唤醒0
0抢到锁
0释放锁
1抢到锁
1释放锁
唤醒完成0执行完
2.唤醒1
1抢到锁
1释放锁
0抢到锁
0释放锁
唤醒完成
1执行完
3.notifyAll()
notifyAll() 方法是用来唤醒当前对象的所有调用 wait() 的线程.
package com.source.object;
/**
* @author dongguanghui
* @date 2024/1/19 16:53
*/
public class Wait3 {
public static void main(String[] args) {
Object object = new Object();
Thread thread0 = new Thread(() -> {
synchronized (object) {
System.out.println("0抢到锁");
try {
System.out.println("0释放锁");
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("0执行完");
}
});
Thread thread1 = new Thread(() -> {
synchronized (object) {
System.out.println("1抢到锁");
try {
System.out.println("1释放锁");
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1执行完");
}
});
Thread thread2 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (object) {
object.notifyAll();
System.out.println("唤醒完成");
}
});
thread0.start();
thread1.start();
thread2.start();
}
}
执行结果有两种情况,取决于唤醒之后,谁先抢到锁
1.1先抢到
0抢到锁
0释放锁
1抢到锁
1释放锁
唤醒完成
1执行完
0执行完
2.0先抢到
1抢到锁
1释放锁
0抢到锁
0释放锁
唤醒完成
0执行完
1执行完