Object中的wait()和notify()
使用注意事项:
1、因为wait需释放锁,所以必须在synchronized中使用(没有锁时使用会抛出IllegalMonitorStateException)
2、notify也要在synchronized使用,并且应该指定对象
3、synchronized(),wait(),notify() 对象必须一致,一个synchronized()代码块中只能有1个线程wait()或notify()
package com.example.springboot.thread; public class WaitTest { public static void main(String[] args) { ThreadA ta = new ThreadA("ta"); ThreadA ta2 = new ThreadA("ta2"); synchronized(ta) { // 通过synchronized(ta)获取“对象ta的同步锁” try { System.out.println(Thread.currentThread().getName()+" start ta"); ta.start(); ta2.start(); System.out.println(Thread.currentThread().getName()+" block"); // 当前运行中的线程即主线程等待 ta.wait(); //ta2.wait();//因为此代码块中的锁已经给线程ta了,所以运行时此行代码会报IllegalMonitorStateException System.out.println(Thread.currentThread().getName()+" continue"); } catch (InterruptedException e) { e.printStackTrace(); } } } static class ThreadA extends Thread{ public ThreadA(String name) { super(name); } public void run() { synchronized (this) { // 通过synchronized(this)获取“当前对象的同步锁” System.out.println(Thread.currentThread().getName()+" wakup others"); notify(); // 唤醒“当前对象上的等待线程” } } } }
LockSupport中的park() 和 unpark()
1、LockSupport中的park() 和 unpark() 的作用分别是阻塞线程和解除阻塞线程,而且park()和unpark()不会遇到“Thread.suspend 和 Thread.resume所可能引发的死锁”问题。
2、park和wait的区别。wait让线程阻塞前,必须通过synchronized获取同步锁。
package com.example.springboot.thread; import java.util.concurrent.locks.LockSupport; public class LockSupportTest { private static Thread mainThread; public static void main(String[] args) { ThreadA ta = new ThreadA("ta"); // 获取主线程 mainThread = Thread.currentThread(); System.out.println(Thread.currentThread().getName()+" start ta"); ta.start(); System.out.println(Thread.currentThread().getName()+" block"); // 主线程阻塞 LockSupport.park(mainThread); System.out.println(Thread.currentThread().getName()+" continue"); } static class ThreadA extends Thread{ public ThreadA(String name) { super(name); } public void run() { System.out.println(Thread.currentThread().getName()+" wakup others"); // 唤醒“主线程” LockSupport.unpark(mainThread); } } }