Object中的wait()
、notify()
让线程等待和唤醒
Object.wait()
、Object.notify()
方法必须再synchronized
修饰的代码块中才能正常使用,否则会报异常(语法不会显示有错误
)
如下如果注释synchronized (obj)
会报java.lang.IllegalMonitorStateException: current thread is not owner
正常使用必须在synchronized中使用!
public static void main(String[] args) {
Object obj = new Object();
new Thread(() -> {
// synchronized (obj) {
System.out.println(Thread.currentThread().getName() + "\t======== 进入");
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "\t======== 被唤醒");
// }
}, "A").start();
new Thread(() -> {
//synchronized (obj) {
obj.notify();
System.out.println(Thread.currentThread().getName()+"\t============ 通知");
//}
}, "B").start();
}
Condition中的await()
、signal()
让线程等待和唤醒
Condition需要在ReentrantLock下使用,也就是需要上锁和释放锁,否则也会报java.lang.IllegalMonitorStateException
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition=lock.newCondition();
new Thread(() -> {
// lock.lock();
System.out.println(Thread.currentThread().getName() + "\t======== 进入");
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
// lock.unlock();
}
System.out.println(Thread.currentThread().getName() + "\t======== 被唤醒");
}, "A").start();
new Thread(() -> {
// lock.lock();
try {
condition.signal();
System.out.println(Thread.currentThread().getName()+"\t============ 通知");
} finally {
// lock.unlock();
}
}, "B").start();
}
LockSupport中的park()
、unpark()
LockSupport调用unpark方法最多只发放一个许可证
,调用park则需要消耗一个许可证。
换而言之
如下的逻辑虽然调用了两次unpark,但LockSupport只发放一个许可证
LockSupport.unpark(t1)//需要传入参数线程t1
LockSupport.unpark(t1)//需要传入参数线程t1
LockSupport.park()
LockSupport.park()// 线程会阻塞
另外LockSupport.park()和LockSupport.unpark()不影响正常使用阻塞
LockSupport.unpark(t1)//需要传入参数线程t1
LockSupport.park()
// 上面的顺序和下面的调用顺序,两者的作用相同
LockSupport.park()
LockSupport.unpark(t1)//需要传入参数线程t1
总而概之,LockSupport是一个线程阻塞的工具类,里面的所有方法都是静态的