文章中的
Console.log()
使用的是 hutool工具
- 方式1和方式2,必须搭配锁使用,而方式3可以不使用锁
1、使用wait
notify
synchronized
实现线程唤醒机制
实现线程唤醒机制,但不保证是精确唤醒
private static void imp1() {
final Object lock = new Object();
new Thread(() -> {
synchronized (lock) {
Console.log("{} 开始等待...", Thread.currentThread().getName());
try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}
Console.log("{} 被唤醒", Thread.currentThread().getName());
}
}, "线程1").start();
new Thread(() -> {
synchronized (lock) {
try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}
Console.log("{} 执行唤醒操作", Thread.currentThread().getName());
lock.notify();
}
}, "线程2").start();
}
2、使用 ReentrantLock
,Condition
的await
和signal
方法
可以实现精确唤醒
private static void imp2() {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
new Thread(() -> {
lock.lock();
try {
Console.log("{} 开始等待...", Thread.currentThread().getName());
condition.await();
Console.log("{} 被唤醒", Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}, "线程1").start();
new Thread(() -> {
lock.lock();
try {
TimeUnit.SECONDS.sleep(1);
Console.log("{} 执行唤醒操作", Thread.currentThread().getName());
condition.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}, "线程2").start();
}
3、使用 LockSupport
的park()
,unpark(线程1)
方法
可以实现精确唤醒
注意下面休眠位置
,unpark
可以在 park
之前执行,这样 t1线程在执行到park处的时候,不会阻塞
private static void imp3() {
Thread t1 = new Thread(() -> {
try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
Console.log("{} 开始等待...LockSupport", Thread.currentThread().getName());
LockSupport.park();
Console.log("{} 被唤醒", Thread.currentThread().getName());
}, "线程1");
t1.start();
Thread t2 = new Thread(() -> {
Console.log("{} 执行唤醒操作", Thread.currentThread().getName());
LockSupport.unpark(t1);
}, "线程2");
t2.start();
}