Java多线程学习(二)wait、notify、notifyAll详解
目录
一、整体图表
二、具体方法
2.1 wait方法
2.1.1定义
让线程进入等待并且释放锁。
2.1.2注意
- 当前线程必须持有该对象的锁
-
wait
必须被唤醒后或者设置时间进入队列才能继续执行接下来的操作
2.1.3使用方式
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Thread1());
thread3.start();
}
static class Thread1 implements Runnable {
@Override
public void run() {
//比如在同步代码块或者方法里且得到该对象的锁
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " is running.");
try {
//对象进入等待
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " get the lock.");
}
}
}
2.2 notify方法
2.2.1定义
唤醒任意一个等待的锁。
2.2.2注意
- 当前线程必须持有该对象的锁
-
notify
后会唤醒一个正在等待的线程 - 但是当前线程不会马上放弃锁的持有权,而是在同步代码执行完毕后才会释放锁
2.2.2 使用方式
//步骤
//1.先让线程0执行然后进行等待
//2.再让线程1执行然后通过 notify 唤醒0线程(因为等待队列只有0线程)
//3.线程1执行结束后会执行线程0
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Thread1());
Thread thread2 = new Thread(new Thread2());
thread1.start();
Thread.sleep(1000);
thread2.start();
}
static class Thread1 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " running.");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " get the lock.");
}
}
}
static class Thread2 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " is running.");
object.notify();
System.out.println(Thread.currentThread().getName() + " invoke notify()");
System.out.println(Thread.currentThread().getName() + " release the lock.");
}
}
}
//结果:
Thread-0 running.
Thread-1 is running.
Thread-1 invoke notify()
Thread-1 release the lock.
Thread-0 get the lock.
2.3 notifyAll
2.3.1定义
唤醒所有在等待的锁。
2.3.2注意
- 当前线程必须持有该对象的锁
-
notify
后会唤醒所有在等待的锁 - 但是当前线程不会马上放弃锁的持有权,而是在同步代码执行完毕后才会释放锁
2.3.3 使用方式
//步骤
//1.先让线程0以及线程1执行然后进行等待
//2.再让线程2执行然后通过 notifyAll
唤醒所有线程
//3.线程2执行结束后会执行线程0和1
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Thread1());
Thread thread2 = new Thread(new Thread2());
Thread thread3 = new Thread(new Thread3());
thread1.start();
thread2.start();
Thread.sleep(1000);
thread3.start();
}
static class Thread1 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " running.");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " get the lock.");
}
}
}
static class Thread2 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " running.");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " get the lock.");
}
}
}
static class Thread3 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " is running.");
object.notifyAll();
System.out.println(Thread.currentThread().getName() + " invoke notifyAll()");
System.out.println(Thread.currentThread().getName() + " release the lock.");
}
}
}
结果:
Thread-0 running.
Thread-1 running.
Thread-2 is running.
Thread-2 invoke notifyAll()
Thread-2 release the lock.
Thread-1 get the lock.
Thread-0 get the lock.