JUC-LockSupport

线程的等待和唤醒的三种方式

1.使用Object中的wait()方法让线程等待,使用Object中的notify()方法唤醒线程,使用必须持有锁

public class LockSupportDemo {
    public static void main(String[] args) {
        Object lockObject = new Object();
        Thread t1 = new Thread(() -> {
            synchronized (lockObject) {
                try {
                    lockObject.wait();
                    System.out.println("t1 被唤醒");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t1");
        t1.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Thread t2 = new Thread(() -> {
            synchronized (lockObject) {
                System.out.println("唤醒t1");
                lockObject.notify();
            }
        }, "t2");

        t2.start();
    }
}
  1. 调用wait()和notify()方法时,必须持有锁,否则报java.lang.IllegalMonitorStateException

  2. 将notify放在wait方法前面,程序无法执行,无法唤醒

2. 使用JUC包中Condition的await()方法让线程等待,使用signal()方法唤醒线程,使用必须持有锁

public class LockSupportCondition {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Condition condition = lock.newCondition();

        new Thread(()->{
           lock.lock();
            System.out.println(Thread.currentThread().getName() + "come in");
            try {
                condition.await();
                System.out.println(Thread.currentThread().getName() + "\t-------waked");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }).start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
            lock.lock();
            condition.signal();
            System.out.println(Thread.currentThread().getName() + "\t-------signal");
            lock.unlock();
        }, "t2").start();
    }
}

  1. 调用await()和signal()方法时,必须持有锁,否则报java.lang.IllegalMonitorStateException

  2. 先await() 后signal,不能反了

3.LockSupport类可以park阻塞当前线程以及unpark唤醒指定被阻塞的线程

LockSupport的方法
在这里插入图片描述
常用方法
park()

  • 如果有凭证,则会直接消耗掉这个凭证然后正常退出
  • 没有凭证,就会阻塞等待凭证可用

unpark()

  • 增加一个凭证,但凭证最多只能有一个

LockSupport是用来创建锁和其他同步类的基本线程阻塞原语
LockSupport类使用一种名为(Permit)许可的概念做到阻塞和唤醒的功能,每个线程都有一个许可(permit),许可的累加上限是1

LockSupport类的特点:

  • 正常+无锁块要求
  • LockSupport支持先唤醒后等待
  • 成双成对
public class LockSupportDemoPark {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "-------come in");
            LockSupport.park();
            System.out.println(Thread.currentThread().getName() + "-------waked");

        }, "t1");
        t1.start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread t2 = new Thread(() -> {
//            System.out.println(Thread.currentThread().getName() + "-------come in");
            LockSupport.unpark(t1);
            System.out.println(Thread.currentThread().getName() + "-------唤醒t1");

        }, "t2");
        t2.start();
    }
}

park unpark 无顺序要求。因为park发了许可证,线程没使用,会保留,许可证不会积累,最多只有一个

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值