Join

主线程join

启动线程t1,随后调用join,main线程需要等t1线程执行完毕后继续执行。

public class MainJoin {

    static class MyThread implements Runnable {

        String name;

        public MyThread(String name) {
this.name = name;
} @Override
public void run() {
System.out.println(name + "开始执行");
try {
//todo 业务逻辑
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "执行完毕");
}
} public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new MyThread("第一个线程"));
Thread t2 = new Thread(new MyThread("第二个线程"));
Thread t3 = new Thread(new MyThread("第三个线程"));
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
}
}

线程池写法

public class ThreadPool {

    private static final ExecutorService executorService = new ThreadPoolExecutor(1, 1, 0L
, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()
, Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); static class MyThread implements Runnable { String name; public MyThread(String name) {
this.name = name;
} @Override
public void run() {
System.out.println(name + "开始执行");
try {
//todo 执行业务逻辑
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "执行完毕");
}
} public static void main(String[] args) {
executorService.submit(new MyThread("第一个线程"));
executorService.submit(new MyThread("第二个线程"));
executorService.submit(new MyThread("第三个线程"));
executorService.shutdown();
}
}

wait notify

这里的原理就是线程t1、t2共用一把锁myLock1,t2先wait阻塞,等待t1执行完毕notify通知t2继续往下执行,线程t2、t3共用一把锁myLock2,t3先wait阻塞,等待t2执行完毕notify通知t3继续往下执行。

public class WaitNotify {

    private static Object myLock1 = new Object();
private static Object myLock2 = new Object(); static class MyThread implements Runnable { String name;
Object startLock;
Object endLock; public MyThread(String name, Object startLock, Object endLock) {
this.name = name;
this.startLock = startLock;
this.endLock = endLock;
} @Override
public void run() {
if (startLock != null) {
synchronized (startLock) {
//阻塞
try {
startLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//继续往下执行
System.out.println(name + "开始执行");
//todo 执行业务逻辑
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (endLock != null) {
synchronized (endLock) {
//唤醒
endLock.notify();
}
}
}
} public static void main(String[] args) {
Thread t1 = new Thread(new MyThread("第一个线程", null, myLock1));
Thread t2 = new Thread(new MyThread("第二个线程", myLock1, myLock2));
Thread t3 = new Thread(new MyThread("第三个线程", myLock2, null));
//打乱顺序执行
t3.start();
t1.start();
t2.start();
} }

Condition

类似 wait notify

public class ConditionDemo {

    private static Lock lock = new ReentrantLock();
private static Condition condition1 = lock.newCondition();
private static Condition condition2 = lock.newCondition(); static class MyThread implements Runnable { String name;
Condition startCondition;
Condition endCondition; public MyThread(String name, Condition startCondition, Condition endCondition) {
this.name = name;
this.startCondition = startCondition;
this.endCondition = endCondition;
} @Override
public void run() {
//阻塞
if (startCondition != null) {
lock.lock();
try {
startCondition.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//继续往下执行
System.out.println(name + "开始执行");
//todo 执行业务逻辑
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//唤醒
if (endCondition != null) {
lock.lock();
try {
endCondition.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
} public static void main(String[] args) {
Thread t1 = new Thread(new MyThread("第一个线程", null, condition1));
Thread t2 = new Thread(new MyThread("第二个线程", condition1, condition2));
Thread t3 = new Thread(new MyThread("第三个线程", condition2, null));
//打乱顺序执行
t3.start();
t2.start();
t1.start();
} }

CountDownLatch

public class CountDownLatchDemo {
static class MyThread implements Runnable {
CountDownLatch startCountDown;
CountDownLatch endCountDown; public MyThread(CountDownLatch startCountDown, CountDownLatch endCountDown) {
this.startCountDown = startCountDown;
this.endCountDown = endCountDown;
} @Override
public void run() {
//阻塞
if (startCountDown != null) {
try {
startCountDown.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//执行自己的业务逻辑
System.out.println(Thread.currentThread().getName() + "开始执行");
//todo 执行业务逻辑
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (endCountDown != null) {
endCountDown.countDown();
}
}
} public static void main(String[] args) {
CountDownLatch countDownLatch1 = new CountDownLatch(1);
CountDownLatch countDownLatch2 = new CountDownLatch(1);
Thread t1 = new Thread(new MyThread(null, countDownLatch1), "第一个线程");
Thread t2 = new Thread(new MyThread(countDownLatch1, countDownLatch2), "第二个线程");
Thread t3 = new Thread(new MyThread(countDownLatch2, null), "第三个线程");
//打乱顺序执行
t3.start();
t2.start();
t1.start();
}
} 等待多线程完成的CountDownLatch
public static void main(String[] args) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(5); for (int i = 0; i < 5; i++) { new Thread(() -> { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("子线程执行"); latch.countDown(); }).start(); } latch.await(); System.out.println("主线程执行"); }

CompletableFutureDemo

public class CompletableFutureDemo {

    static class MyThread implements Runnable {
@Override
public void run() {
System.out.println("执行 : " + Thread.currentThread().getName());
}
} public static void main(String[] args) {
Thread t1 = new Thread(new MyThread(), "线程1");
Thread t2 = new Thread(new MyThread(), "线程2");
Thread t3 = new Thread(new MyThread(), "线程3");
CompletableFuture.runAsync(t1::start).thenRun(t2::start).thenRun(t3::start);
}
}

[Thread] 多线程顺序执行的更多相关文章

  1. C# 不使用Task实现的多线程顺序执行

    多线程有很好的并发性即无序性,在某些特殊情况下需要用到多线程然而又要使其具备顺序性,这种时候就有了一个特殊的场景那就是多线程顺序执行,在现在VS2015中Task自带了顺序执行的方法,但在此之前的旧项 ...

  2. java保证多线程的执行顺序

    1. java多线程环境中,如何保证多个线程按指定的顺序执行呢? 1.1 通过thread的join方法保证多线程的顺序执行, wait是让主线程等待 比如一个main方法里面先后运行thread1, ...

  3. jmeter Thread Groups的顺序执行与并行执行

    本期目标: 理解Thread Groups的顺序执行与并行执行 控制因子:Run Thread Groups consecutively(i.e.one at time) 预期结论: 1.勾选 Run ...

  4. C#之使用AutoResetEvent实现线程的顺序执行

    前几天一朋友问我如何实现线程的顺序执行,说真的,虽然看过CLR这本书,也把线程部分拜读了两遍,但是这个问题出来之后还是没有一个思路.今天在搜索资料的时候无意中再次看到AutoResetEvent这个东 ...

  5. ASP.NET 多线程 监控任务执行情况,并显示进度条

    关于多线程的基本概念和知识在本文中不多讲,而且我懂的也不是很透,说的太多误人子弟...对于我来说,做本文提到的功能够用就行,等实现其他效果不够用的时候,再深入研究 推荐看园子里的两篇博客应该就有个基本 ...

  6. 多线程并发执行任务,取结果归集。终极总结:Future、FutureTask、CompletionService、CompletableFuture

    目录 1.Futrue 2.FutureTask 3.CompletionService 4.CompletableFuture 5.总结 ================正文分割线========= ...

  7. .NET进阶篇06-async异步、thread多线程1

    知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂 异步多线程挺大一块内容,既想拆开慢慢学,又想一股脑全倒出.纠结再三,还是拆开吃透,也不至于篇幅过长,劝退许多人 本篇先做一个概述,列明一些基本概 ...

  8. 面试官:Java中线程是按什么顺序执行的?

    摘要:Java中多线程并发的执行顺序历来是面试中的重点,掌握Java中线程的执行顺序不仅能够在面试中让你脱颖而出,更能够让你在平时的工作中,迅速定位由于多线程并发问题导致的"诡异" ...

  9. Java中如何保证线程顺序执行

    只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的.如果只是创建三个线程然后执行,最后的执行顺序是不可预期的.这是因为在创建完线程之后,线程执行的开始时间取决于CPU何时分配时间片,线程 ...

随机推荐

  1. React Native环境配置、初始化项目、打包安装到手机,以及开发小知识

    1.前言 环境:Win10 + Android 已经在Windows电脑上安装好 Node(v14+).Git.Yarn. JDK(v11) javac -version javac 11.0.15. ...

  2. 技术分享 | ARM下中标麒麟系统ky10使用Xtrabackup-8.0.25

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 一.需求背景 查询Percona官方手册,Xtrabackup 8.0可以备份M ...

  3. 跟我学Python图像处理丨基于灰度三维图的图像顶帽运算和黑帽运算

    摘要:本篇文章结合灰度三维图像讲解图像顶帽运算和图像黑猫运算,通过Python调用OpenCV函数实现. 本文分享自华为云社区<[Python图像处理] 十三.基于灰度三维图的图像顶帽运算和黑帽 ...

  4. HCIA-Datacom 4.1 实验一:访问控制列表配置实验

    实验介绍 访问控制列表ACL(Access Control List)是由一条或多条规则组成的集合.所谓规则,是指描述报文匹配条件的判断语句,这些条件可以是报文的源地址.目的地址.端口号等.ACL本质 ...

  5. html网页乱码原因以及解决办法

    一.乱码造成原因 1.如果网页源代码是gbk编写的,而内容中的文字是utf-8的,那么,此时打开浏览器就会出现HTML乱码.反之也会出现乱码. 2.HTML网页编码是gbk,但是程序从程序库中调出呈现 ...

  6. (已解决)Adobe Creative Cloud 安装 Acrobat PDF 报错 DW071 DW003

    今天安装 Adobe Acrobat pdf 阅读器报错了,错误为 Exit Code: 7 Please see specific errors below for troubleshooting. ...

  7. vsftpd 操作手册 - 完整版

    vsftpd # 目录 - ftp 简介 - vsftpd 简介 - vsftpd 安装&卸载 - vsftpd 配置文件 - vsftpd 认证模板 - vsftpd 配置模板 # 目录详解 ...

  8. 【unity游戏入门】1 环境安装

    作者 罗芭Remoo 2021年9月24日 这一个系列随笔记录如何使用unity引擎从零开始开发游戏,软件版本均使用最新版本 有关unity的背景介绍可以通过unity官网https://unity. ...

  9. 第七十一篇:Vue组件的私有和全局注册

    好家伙, 1.组件的父子关系 我们封装三个组件,分别为left组件,right组件和App组件 在封装时: 在封装时,彼此的关系是独立的,并不存在父子关系 在使用时: 在使用时,根据彼此的嵌套关系,形 ...

  10. docker容器数据卷的使用

    什么是容器数据卷 docker的理念回顾 将应用和运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对于数据的要求,是希望能够持久化的! 就好比,你安装一个MySQL,结果你把容器删了,就相当于 ...