Object类的wait/notify和LockSupport(park/unpark)的区别

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);
        }
    }
}

区别

park函数是将当前调用Thread阻塞,而unpark函数则是将指定线程Thread唤醒。

与Object类的wait/notify机制相比,park/unpark有两个优点:

  1. 以thread为操作对象更符合阻塞线程的直观定义
  2. 操作更精准,可以准确地唤醒某一个线程。

区别是:notify随机唤醒一个线程,notifyAll唤醒所有等待的线程,增加了灵活性

你可能感兴趣的:(JAVA基础)