[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何时分配时间片,线程 ...
随机推荐
- vue-resource && axios
1 # axios 2 # 1.安装:npm i axios 3 # 2.使用: 4 import axios from 'axios' 5 axios.get(URL).then(response= ...
- 论文翻译:2022_Time-Frequency Attention for Monaural Speech Enhancement
论文地址:单耳语音增强的时频注意 引用格式:Zhang Q, Song Q, Ni Z, et al. Time-Frequency Attention for Monaural Speech Enh ...
- 用JavaScript写输入框的校验
//Script function cheack(){ var kong = ''//获取值不能放外面,不然一直为空 kong = document.getElementById('name').va ...
- 巧用Prometheus来扩展kubernetes调度器
Overview 本文将深入讲解 如何扩展 Kubernetes scheduler 中各个扩展点如何使用,与扩展scheduler的原理,这些是作为扩展 scheduler 的所需的知识点.最后会完 ...
- CSP-J2021 题解
分糖果 题意 选择L~R中的某个数 , 使得x mod k的结果最大. 思路 分两种情况考虑: 若 L 和 R 对 K 取模后在同一区间,则必然在 x=R 位置取到最大值: 否则 L~R 必然跨越多个 ...
- Docker容器网络配置
Docker容器网络配置 1.Linux内核实现名称空间的创建 1.1 ip netns命令 可以借助ip netns命令来完成对 Network Namespace 的各种操作.ip netns命令 ...
- 如何构建 Apache DolphinScheduler 的 Docker 镜像
继昨日发布第一个 [官方 Docker 镜像] 后,有几位小伙伴私信想自己进行编译,这里也将 Docker 的主要贡献者文禾同学整理的文档进行分享.以下是全文内容: 您能够在类 Unix 系统和 Wi ...
- Hive存储格式之ORC File详解,什么是ORC File
目录 概述 文件存储结构 Stripe Index Data Row Data Stripe Footer 两个补充名词 Row Group Stream File Footer 条纹信息 列统计 元 ...
- 【lwip】005-lwip内核框架剖析
目录 前言 5.1 lwip初始化 5.2 内核超时 5.2.1 内核超时机制 5.2.2 周期定时机制 5.2.3 内核超时链表数据结构 5.2.4 内核超时初始化 5.2.6 超时的溢出处理 5. ...
- 美团组件化事件总线方案改进:ModularEventBus
请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · AndroidFamily 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭锐] ...