4种方法实现多线程按着指定顺序执行

点击上方“Java基基”,选择“设为星标”

做积极的人,而不是积极废人!

每天 14:00 更新文章,每天掉亿点点头发...

源码精品专栏

来源:blog.csdn.net/jqc874789596/

article/details/100557300


文章介绍4种方法,简单易懂,通过4个demo抛砖引玉。

在子线程中通过join()方法指定顺序

通过join()方法使当前线程“阻塞”,等待指定线程执行完毕后继续执行。

举例:在线程thread2中,加上一句thread1.join(),其意义在于,当前线程2运行到此行代码时会进入阻塞状态,直到线程thread1执行完毕后,线程thread2才会继续运行,这就保证了线程thread1与线程thread2的运行顺序。

public class ThreadJoinDemo {
  public static void main(String[] args) throws InterruptedException {
    final Thread thread1 = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("打开冰箱!");
      }
    });

    final Thread thread2 = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          thread1.join();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("拿出一瓶牛奶!");
      }
    });

    final Thread thread3 = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          thread2.join();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("关上冰箱!");
      }
    });

    //下面三行代码顺序可随意调整,程序运行结果不受影响,因为我们在子线程中通过“join()方法”已经指定了运行顺序。
    thread3.start();
    thread2.start();
    thread1.start();

  }
}

运行结果:

打开冰箱!
        拿出一瓶牛奶!
        关上冰箱!

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。

项目地址:https://github.com/YunaiV/ruoyi-vue-pro

在主线程中通过join()方法指定顺序

简单说一下子线程与主线程的区别,子线程指的是发生在Thread内部的代码,主线程指的是发生在main函数中的代码,我们可以在main函数中通过join()方法让主线程阻塞等待以达到指定顺序执行的目的。

public class ThreadMainJoinDemo {
  public static void main(String[] args) throws InterruptedException {
    final Thread thread1 = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("打开冰箱!");
      }
    });

    final Thread thread2 = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("拿出一瓶牛奶!");
      }
    });

    final Thread thread3 = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("关上冰箱!");
      }
    });

    thread1.start();
    thread1.join();
    thread2.start();
    thread2.join();
    thread3.start();
  }
}

输出结果:

打开冰箱!
        拿出一瓶牛奶!
        关上冰箱!

基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。

项目地址:https://github.com/YunaiV/onemall

通过倒数计时器CountDownLatch实现

CountDownLatch通过计数器提供了更灵活的控制,只要检测到计数器为0当前线程就可以往下执行而不用管相应的thread是否执行完毕。

public class ThreadCountDownLatchDemo {

  private static CountDownLatch countDownLatch1 = new CountDownLatch(1);

  private static CountDownLatch countDownLatch2 = new CountDownLatch(1);

  public static void main(String[] args) {
    final Thread thread1 = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("打开冰箱!");
        countDownLatch1.countDown();
      }
    });

    final Thread thread2 = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          countDownLatch1.await();
          System.out.println("拿出一瓶牛奶!");
          countDownLatch2.countDown();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    });

    final Thread thread3 = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          countDownLatch2.await();
          System.out.println("关上冰箱!");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    });

    //下面三行代码顺序可随意调整,程序运行结果不受影响
    thread3.start();
    thread1.start();
    thread2.start();
  }
}

输出结果:

打开冰箱!
        拿出一瓶牛奶!
        关上冰箱!

通过创建单一化线程池newSingleThreadExecutor()实现

单线程化线程池(newSingleThreadExecutor)的优点,串行执行所有任务。

public class ThreadPoolDemo {

  static ExecutorService executorService = Executors.newSingleThreadExecutor();

  public static void main(String[] args) {
    final Thread thread1 = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("打开冰箱!");
      }
    });

    final Thread thread2 =new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("拿出一瓶牛奶!");
      }
    });

    final Thread thread3 = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("关上冰箱!");
      }
    });
    executorService.submit(thread1);
    executorService.submit(thread2);
    executorService.submit(thread3);
    executorService.shutdown();        //使用完毕记得关闭线程池
  }

}

输出结果:

打开冰箱!
        拿出一瓶牛奶!
        关上冰箱!


欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值