[Thread] 多线程顺序执行
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] 多线程顺序执行的更多相关文章
- C# 不使用Task实现的多线程顺序执行
多线程有很好的并发性即无序性,在某些特殊情况下需要用到多线程然而又要使其具备顺序性,这种时候就有了一个特殊的场景那就是多线程顺序执行,在现在VS2015中Task自带了顺序执行的方法,但在此之前的旧项 ...
- java保证多线程的执行顺序
1. java多线程环境中,如何保证多个线程按指定的顺序执行呢? 1.1 通过thread的join方法保证多线程的顺序执行, wait是让主线程等待 比如一个main方法里面先后运行thread1, ...
- jmeter Thread Groups的顺序执行与并行执行
本期目标: 理解Thread Groups的顺序执行与并行执行 控制因子:Run Thread Groups consecutively(i.e.one at time) 预期结论: 1.勾选 Run ...
- C#之使用AutoResetEvent实现线程的顺序执行
前几天一朋友问我如何实现线程的顺序执行,说真的,虽然看过CLR这本书,也把线程部分拜读了两遍,但是这个问题出来之后还是没有一个思路.今天在搜索资料的时候无意中再次看到AutoResetEvent这个东 ...
- ASP.NET 多线程 监控任务执行情况,并显示进度条
关于多线程的基本概念和知识在本文中不多讲,而且我懂的也不是很透,说的太多误人子弟...对于我来说,做本文提到的功能够用就行,等实现其他效果不够用的时候,再深入研究 推荐看园子里的两篇博客应该就有个基本 ...
- 多线程并发执行任务,取结果归集。终极总结:Future、FutureTask、CompletionService、CompletableFuture
目录 1.Futrue 2.FutureTask 3.CompletionService 4.CompletableFuture 5.总结 ================正文分割线========= ...
- .NET进阶篇06-async异步、thread多线程1
知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂 异步多线程挺大一块内容,既想拆开慢慢学,又想一股脑全倒出.纠结再三,还是拆开吃透,也不至于篇幅过长,劝退许多人 本篇先做一个概述,列明一些基本概 ...
- 面试官:Java中线程是按什么顺序执行的?
摘要:Java中多线程并发的执行顺序历来是面试中的重点,掌握Java中线程的执行顺序不仅能够在面试中让你脱颖而出,更能够让你在平时的工作中,迅速定位由于多线程并发问题导致的"诡异" ...
- Java中如何保证线程顺序执行
只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的.如果只是创建三个线程然后执行,最后的执行顺序是不可预期的.这是因为在创建完线程之后,线程执行的开始时间取决于CPU何时分配时间片,线程 ...
随机推荐
- Mybatis的使用(4)
1:解决实体类成员变量和数据库表中字段名称不一致的问题: 方法1:在写sql语句时,给表中的列名起别名,名字和实体类名称一样 方法2:使用resultMap来解决: 例如:实体类中成员变量为id,na ...
- 【原创】Magisk Root隐藏模块 Shamiko安装
本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! Root隐藏模块 Shamiko安装 操 ...
- [护网杯 2018]easy_tornado-1|SSTI注入
1.打开之后给出了三个连接,分别查看下三个连接内得信息,结果如下: 2.url中参数包含一个文件名与一串应该是md5得加密的字符串,文件名已经获得了,就需要获取加密得字符串,但是加密字符串时需要使用到 ...
- Java SE 8 新增特性
Java SE 8 新增特性 作者:Grey 原文地址: Java SE 8 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...
- Luogu2915 [USACO08NOV]奶牛混合起来Mixed Up Cows (状压DP)
枚举末位状态 #include <iostream> #include <cstdio> #include <cstring> #include <algor ...
- Luogu3402【模板】可持久化并查集 (主席树)
用\(depth\)按秩合并,不能直接启发,数组开40倍左右 #include <iostream> #include <cstdio> #include <cstrin ...
- Go语言Tips
时间日期格式化 time.Now().Format("2006-01-02") 原生DefaultServeMux支持restful路由 ref: https://towardsd ...
- RabbitMQ 入门系列:2、基础含义理解:链接、通道、队列、交换机
系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...
- [NOIP2018提高组] 保卫王国 (树链剖分+动态DP)
题面 题目链接-Luogu 题目链接-Loj(要加Freopen) 题解 什么是动态DP? OneInDark:你不需要知道这么多,你只需要知道是利用了广义矩阵乘法就够了! 广义矩乘 广义矩阵乘法,简 ...
- 钓鱼利用-CVE-2018-20250
钓鱼利用-CVE-2018-20250 漏洞影响版本 WinRAR < 5.70 Beta 1 Bandizip< = 6.2.0.0 好压(2345压缩) < = 5.9.8.10 ...
