Java多线程之控制执行顺序
概念: 多线程在并发环境中的正常执行顺序是随机无序的,并不能按照期盼的结果输出。
因为启动一个线程时,线程并不会立即执行,而是等待CPU的资源调度,CPU能调度哪个线程,是通过多种复杂的算法计算而来。
(一)Thread的join()方法来解决这个问题
一般在多线程编程时,需要控制线程的先后执行顺序,比如:主线程中写了子线程t1,想要的效果是需要t1先执行,然后再执行接下来的主线程操作,但是默认的是主线程先执行,所以问题就出现了,执行结果与预期结果不一致。
有两个线程t1和t2,现在让t1比t2先执行:
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
Sysout.out.print("t1");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
// 引入t1线程,等待t1线程的run方法执行完 ,t2才会继续执行
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Sysout.out.print("t2");
}
});
t2.start();
t1.start();
执行结果t1 t2
总结:
多线程编程时,可通过join()方法控制线程的先后执行顺序。 join方法:让主线程等待子线程运行结束后再继续运行
(二) 单一线程池 Excutors.newSingleThreadExecutor()
public class Test {
private static ExecutorService executor = Executors.newSingleThreadExecutor();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new MyThread1());
Thread t2 = new Thread(new MyThread2());
Thread t3 = new Thread(new MyThread3());
executor.submit(t1);
executor.submit(t2);
executor.submit(t3);
executor.shutdown();
}
}
总结:
利用并发包里的Excutors的newSingleThreadExecutor产生一个单线程的线程池,
而这个线程池的底层原理就是一个先进先出(FIFO)的队列。
代码中executor.submit依次添加了t1 t2 t3线程,按照FIFO的特性,执行顺序也就是t1 t2 t3的执行结果,从而保证了执行顺序。
(三)使用CountDownLatch
final int count = 10; // 计数次数
final CountDownLatch latch = new CountDownLatch(count);//创建CountDownLatch 实例 预定计数次数:10
for (int i = 0; i < count; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
// do anything
System.out.println("线程"
+ Thread.currentThread().getId());
} catch (Throwable e) {
// whatever
} finally {
// 很关键, 无论上面程序是否异常必须执行countDown,否则await无法释放
latch.countDown();//递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
// 如果当前计数大于零,则将计数减少 1
}
}
}).start();
}
try {
// 10个线程countDown()都执行之后才会释放当前线程,程序才能继续往后执行
latch.await();
} catch (InterruptedException e) {
// whatever
}
System.out.println("Finish");
输出:
线程14
线程13
线程15
线程18
线程20
线程17
线程16
线程22
线程21
线程19
Finish
总结:
java.util.concurrent.CountDownLatch
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
用给定的计数初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。
到达0之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。
最常见的使用场景: 等待其他线程处理完才继续当前线程。
最重要的是使用非常简单!
参考:https://blog.csdn.net/u013407384/article/details/79999022
Java多线程之控制执行顺序的更多相关文章
- Java Object 构造方法的执行顺序
Java Object 构造方法的执行顺序 @author ixenos 为了使用类而做的准备工作包括三个步骤 1)加载:类加载器查找字节码(一般在classpath中找),从字节码创建一个Class ...
- 夯实Java基础系列7:一文读懂Java 代码块和执行顺序
目录 Java中的构造方法 构造方法简介 构造方法实例 例 1 例 2 Java中的几种构造方法详解 普通构造方法 默认构造方法 重载构造方法 java子类构造方法调用父类构造方法 Java中的代码块 ...
- 夯实Java基础系列7:Java 代码块和执行顺序
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- (转)java for循环的执行顺序和几种常用写法
算是温习吧.问题比较基础,但是也比较重要.(虽然是C,但是很经典) for循环可以说在每个程序中都少不了的,语句头包括三个部分:初始化,判读条件,一个表达式. 但是这三个部分的执行顺序是什么,这是我们 ...
- java中静态代码执行顺序
1.Java中静态变量只能在类主体中定义,不能在方法中定义. 静态变量属于类所有而不属于方法. 2. 静态块:用static申明,JVM加载类时执行,仅执行一次 构造块:类中直接用{}定义,每一次创建 ...
- java 方法参数的执行顺序
java方法的参数的执行顺序是从左到右还是从右到左呢? 写出一下测试程序: 1 import java.util.*; 2 import java.io.*; 3 public class Test ...
- [转]多个ajax请求时控制执行顺序或全部执行后的操作
本文转自:https://blog.csdn.net/fsdad/article/details/71514822 一.当确保执行顺序时: 1. 请求加async: false,,这样所有的ajax就 ...
- 多个ajax请求时控制执行顺序或全部执行后的操作
1.当确保执行顺序时 (1)请求加async: false,,这样所有的ajax就会同步执行,请求顺序就是代码顺序: (2)$.when 确保所有异步的ajax请求完毕时 $.when($.aja ...
- Java初始化块及执行顺序
理解 初始化块又称为代码块.属于类中的第四大成员.本质上是一个方法,它也有方法体,但没有方法名,没有参数,没有返回,而且也不是通过对象或类名显式调用,而是通过隐式调用 是构造器的补充 语法 [修饰符] ...
随机推荐
- 二叉树的python可视化和常用操作代码
二叉树是一个重要的数据结构, 本文基于"二叉查找树"的python可视化 pybst 包, 做了一些改造, 可以支持更一般的"二叉树"可视化. 关于二叉树和二叉 ...
- Retrofit GreenDao开发中遇到的坑
持续更新中1.使用@FormUrlEncoded的话,服务端需要使用Request.Form,如果不使用@FormUrlEncoded本地需要由 @FieldMap Map<String, Ob ...
- 微信小程序开发(2) 计算器
在这篇微信小程序开发教程中,我们将介绍如何使用微信小程序开发计算器功能. 本文主要分为两个部分,小程序主体部分及计算器业务页面部分 一.小程序主体部分 一个小程序主体部分由三个文件组成,必须放在项目的 ...
- Groovy 设计模式 -- 借贷
借贷模式 http://groovy-lang.org/design-patterns.html#_loan_my_resource_pattern The Loan my Resource patt ...
- dubbo 初探
dubbo官网:http://dubbo.io Dubbo背景和简介(摘自 http://blog.csdn.net/noaman_wgs/article/details/70214612) Dubb ...
- pycharm上传代码到github
一.配置pycharm 点击create API,添加自己的github账号,切记将clone git 那个对勾去掉,不然会报: Successfully created project ‘…’ on ...
- Redis Fun使用
using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Configuration; using Sy ...
- LinkedHashMap实现LRU缓存算法
LinkedHashMap的get()方法除了返回元素之外还可以把被访问的元素放到链表的底端,这样一来每次顶端的元素就是remove的元素. 构造函数如下: public LinkedHashMap ...
- [js]使用百度编辑器uediter时遇到的一些问题(span,div等被过滤)
在使用uediter编辑html代码的时候,div,span等标签会莫名其妙的被过滤掉,然后上网查资料,改了点配置: 1:在ueiter.all.js中找到allowDivTransToP me.se ...
- json 的类型
json靠双引号与单引号, 区分是NUMBER 还是 STRING