线程等待和唤醒的三种方式(Object、Condition、LockSupport)

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是一个线程阻塞的工具类,里面的所有方法都是静态的

相关文章:

1、LockSupport源码的简化

2、LockSupport中文文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诗水人间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值