• 线程等待唤醒几种方法


    线程等待和唤醒有三种实现方法,分别是Object类中的wait、notify;Condition类中的await、signal;LockSupport类中的park、unpark方法。

    1、Object类中的wait、notify必须配合Synchronized关键字一起使用,否则会抛出IllegalMonitorStateException异常,并且notify唤醒需要在wait之后,否则无法唤醒。

    1. public static void main(String[] args) {
    2. Object o = new Object();
    3. new Thread(()->{
    4. synchronized (o) {
    5. try {
    6. o.wait();
    7. } catch (InterruptedException e) {
    8. throw new RuntimeException(e);
    9. }
    10. System.out.println("被唤醒");
    11. }
    12. }).start();
    13. System.out.println("准备唤醒");
    14. synchronized (o) {
    15. o.notify();
    16. }
    17. }

    2、Condition类中的await、signal必须配合Lock.lock、unlock一起使用,否则会抛出IllegalMonitorStateException异常,并且signal唤醒需要在await之后使用,否则无法唤醒。

    1. public static void main(String[] args) {
    2. Lock reentrantLock = new ReentrantLock();
    3. Condition condition = reentrantLock.newCondition();
    4. new Thread(()->{
    5. reentrantLock.lock();
    6. try {
    7. condition.await();
    8. System.out.println("被唤醒");
    9. } catch (InterruptedException e) {
    10. throw new RuntimeException(e);
    11. } finally {
    12. reentrantLock.unlock();
    13. }
    14. }).start();
    15. System.out.println("准备唤醒");
    16. reentrantLock.lock();
    17. try {
    18. condition.signal();
    19. Thread.sleep(1000);
    20. } catch (InterruptedException e) {
    21. throw new RuntimeException(e);
    22. } finally {
    23. reentrantLock.unlock();
    24. }
    25. }

    3、LockSupport类中的park、unpark属于静态方法,unpark会生成许可证,park会消费许可证。先调用park如果未生成许可证,那么会阻塞等待unpark生成许可证,并不会抛出异常。他们只和线程关联,且线程最多只能有一个许可证,这意味着每次生成凭证之后,需要等消费完才能继续生成凭证。

    1. public static void main(String[] args) {
    2. Thread thread = new Thread(() -> {
    3. try {
    4. Thread.sleep(1000);
    5. } catch (InterruptedException e) {
    6. throw new RuntimeException(e);
    7. }
    8. LockSupport.park();
    9. System.out.println("被唤醒");
    10. });
    11. thread.start();
    12. System.out.println("准备唤醒");
    13. //断点可以看到unpark先执行,之后执行park
    14. LockSupport.unpark(thread);
    15. //thread.start()在unpark之后无效,线程必须启动才能unpark成功
    16. }

  • 相关阅读:
    如何用c写fastcgi运行在apache下面
    k8s学习笔记4-基础部分pod探针
    Win10安装-我们无法创建新的分区,也找不到现有的分区
    如何对数字货币进行投资分析--基本面
    计算机毕业设计(附源码)python游戏盒子系统
    如何打造一支专业的QA团队,至少要关注这5点
    用饭店来形象比喻线程池的工作原理
    第十七章《MySQL数据库及SQL语言简介》第1节:数据库简介
    云原生Kubernetes:K8S存储卷
    爬虫工作者必备:使用爬虫IP轻松获得最强辅助
  • 原文地址:https://blog.csdn.net/z275598733/article/details/133611332