LockSupport.park unpark 和wait、notify的区别

wait、notify用法

wait、notify、notifyAll是Object对象中提供的用于线程挂起和唤醒的方法。
wait、notify、notifyAll必须与synchronized关键字搭配使用。

wait、notify、notifyAll必须与锁搭配在一块使用的。obj.wait()的适用场景就是当前线程虽然获得了锁obj,但是不满足运行条件,这时会调用obj.wait(),放弃锁obj,并阻塞等待在obj锁对应的等待队列中。当其他线程调用obj.notify()的时候,有可能会将其唤醒,这个时候可能会满足运行条件,也有可能不满足运行条件!这就是synchronized锁的不足之处!

当调用obj.wait()的时候,会将当前线程挂起,并将其加入到obj对应的等待队列中。
而调用obj.notify()的时候,会唤醒obj对应的等待队列中的其中一个线程!
调用obj.notifyAll()的时候,会唤醒obj对应的等待队列中的全部线程。

wait、notify、notifyAll必须在synchronized代码段中使用,要不然会抛出java.lang.IllegalMonitorStateException异常。

Object o = new Object();
synchronized (o){
    o.wait();//将当前线程挂起,并释放o锁
    o.notify();//唤醒一个等待在o锁等待队列的线程
    o.notifyAll();//唤醒等待在o锁等待队列的所有线程
}

注意如果线程1先调用notify(),然后线程2再调用wait()的时候,线程2同样会阻塞。

LockSupport.park、LockSuppot.unpark()

LockSupport.park()、unpark()是JUC中LockSupport类中提供的一个用于线程挂起和唤醒的方法。

LockSupport.park():将当前线程挂起
LockSupport.unpark(Thread t):将线程 t 唤醒

相同点

1、都是用来唤醒和挂起线程的。
2、wait()、notify()、LockSupport.park()、LockSupport.unpark(Thread t)这几个方法都是允许多个线程同时调用的,并且这几个方法都是线程安全的。
原因就是他们几个对应的C++代码中内部包装了基于操作系统的mutex,通过mutex来加锁保证线程安全。

区别

1、LockSupport.park()和unpark()随时随地都可以调用。而wait和notify只能在synchronized代码段中调用

2、LockSupport允许先调用unpark(Thread t),后调用park()。,如果thread1先调用unpark(thread2),然后线程2后调用park(),线程2是不会阻塞的。
如果线程1先调用notify,然后线程2再调用wait的话,线程2是会被阻塞的。

Thread t = Thread.currentThread();
new Thread(){
    @Override
    public void run() {
        LockSupport.unpark(t);
    }
}.start();

Thread.sleep(2000);
LockSupport.park();//不会阻塞

除此之外,LockSupport.unpark(Thread t)相当于是为线程t提供一个运行许可,并且这个许可是不可重叠的。举例子就是如果线程t2连续三次调用了LockSupport.unpark(Thread t),然后线程t调用LockSupport.park()一次就会将许可证用光,若线程t再次调用LockSupport.park()照样会阻塞。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值