JAVA中等待所有线程都执行结束(转2)
场景:
package com.java4all.mypoint;
import java.util.concurrent.CountDownLatch;
public class ThreadTest {
public static void main(String[] args)throws Exception{
System.out.println("主线程正在执行前:"+Thread.currentThread().getName());
test3();
System.out.println("主线程正在执行后:"+Thread.currentThread().getName());
}
public static void test3(){
try {
for (int i = 1 ;i <= 10;i ++){
Thread.sleep(1000);
new Thread(()->{
System.out.println("子线程正在执行:"+Thread.currentThread().getName());
}).start();
}
}catch (Exception ex){
ex.printStackTrace();
}
}
}
执行结果为:
主线程正在执行前:main
子线程正在执行:Thread-0
子线程正在执行:Thread-1
子线程正在执行:Thread-2
子线程正在执行:Thread-3
子线程正在执行:Thread-4
子线程正在执行:Thread-5
子线程正在执行:Thread-6
子线程正在执行:Thread-7
子线程正在执行:Thread-8
主线程正在执行后:main
子线程正在执行:Thread-9
可以看到,子线程还没执行完时,主线程进来了。
1.使用CountDownLatch
示例如下,我们初始化一个CountDownLatch,值为10(子线程个数),然后每次一个子线程执行完后执行一下countDown(),代码示例如下:
package com.java4all.mypoint; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; public class ThreadTest { /**初始化CountDownLatch,值为线程数量*/
private static final CountDownLatch ctl = new CountDownLatch(10); public static void main(String[] args)throws Exception{
System.out.println("主线程正在执行前:"+Thread.currentThread().getName());
test3();
ctl.await(20, TimeUnit.SECONDS);//最多等待20秒,不管子线程完没完
System.out.println("主线程正在执行后:"+Thread.currentThread().getName());
} public static void test3(){
try {
for (int i = 1 ;i <= 10;i ++){
Thread.sleep(1000);
new Thread(()->{
System.out.println("子线程正在执行:"+Thread.currentThread().getName());
}).start();
ctl.countDown();
}
}catch (Exception ex){
ex.printStackTrace();
}
} }
执行结果为:
主线程正在执行前:main
子线程正在执行:Thread-0
子线程正在执行:Thread-1
子线程正在执行:Thread-2
子线程正在执行:Thread-3
子线程正在执行:Thread-4
子线程正在执行:Thread-5
子线程正在执行:Thread-6
子线程正在执行:Thread-7
子线程正在执行:Thread-8
子线程正在执行:Thread-9
主线程正在执行后:main
java8之前的方式写:
线程类:
package com.java4all.mypoint; import java.util.concurrent.CountDownLatch; /**
* Author: yunqing
* Date: 2018/7/23
* Description:
*/
public class MyRunnable implements Runnable{ public CountDownLatch countDownLatch; @Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("子线程正在执行任务,当前线程为:"+Thread.currentThread().getName());
}catch (InterruptedException inex){
inex.printStackTrace();
}finally {
countDownLatch.countDown();
}
} public CountDownLatch getCountDownLatch() {
return countDownLatch;
} public void setCountDownLatch(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
}
测试类:
package com.java4all.mypoint; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; public class ThreadTest { /**初始化CountDownLatch,值为线程数量*/
private static final CountDownLatch ctl = new CountDownLatch(10); public static void main(String[] args)throws Exception{
System.out.println("主线程正在执行前:"+Thread.currentThread().getName());
for(int i = 1;i <= 10;i ++){
MyRunnable runnable = new MyRunnable();
runnable.setCountDownLatch(ctl);
Thread thread = new Thread(runnable); thread.start();
}
ctl.await(20, TimeUnit.SECONDS);//最多等待20秒,不管子线程完没完
System.out.println("主线程正在执行后:"+Thread.currentThread().getName());
} }
结果为:
主线程正在执行前:main
子线程正在执行任务,当前线程为:Thread-1
子线程正在执行任务,当前线程为:Thread-0
子线程正在执行任务,当前线程为:Thread-2
子线程正在执行任务,当前线程为:Thread-3
子线程正在执行任务,当前线程为:Thread-4
子线程正在执行任务,当前线程为:Thread-7
子线程正在执行任务,当前线程为:Thread-6
子线程正在执行任务,当前线程为:Thread-5
子线程正在执行任务,当前线程为:Thread-9
子线程正在执行任务,当前线程为:Thread-8
主线程正在执行后:main
附: 开启一个线程的其他写法:
/**jdk7匿名内部类的写法*/
public static void test1(){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("aaaa");
}
}).start();
} /**
* jdk8
* Runnable是个函数接口,可以利用jdk8的lambda来简写
* 函数接口:是指内部只有一个抽象方法的接口
* */
public static void test2(){
new Thread(()->{
System.out.println("bbb");
}).start();
}
JAVA中等待所有线程都执行结束(转2)的更多相关文章
- java中等待所有线程都执行结束(转)
转自:http://blog.csdn.net/liweisnake/article/details/12966761 今天看到一篇文章,是关于java中如何等待所有线程都执行结束,文章总结得很好,原 ...
- java中等待所有线程都执行结束
转自:http://blog.csdn.net/liweisnake/article/details/12966761 今天看到一篇文章,是关于java中如何等待所有线程都执行结束,文章总结得很好,原 ...
- Java中如何保证线程顺序执行
只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的.如果只是创建三个线程然后执行,最后的执行顺序是不可预期的.这是因为在创建完线程之后,线程执行的开始时间取决于CPU何时分配时间片,线程 ...
- 【java】【多线程】等待开启的多个线程都执行完成,再做事情,怎么实现
今天在controller中写一个接口用来测试模拟多个请求同时到达 下订单的情况, 怎么能有效保证高并发下的库存和销量的一致性呢?[具体实现方法:https://www.cnblogs.com/sxd ...
- Java中的守护线程 & 非守护线程(简介)
Java中的守护线程 & 非守护线程 守护线程 (Daemon Thread) 非守护线程,又称用户线程(User Thread) 用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守 ...
- Java 中如何实现线程间通信
世界以痛吻我,要我报之以歌 -- 泰戈尔<飞鸟集> 虽然通常每个子线程只需要完成自己的任务,但是有时我们希望多个线程一起工作来完成一个任务,这就涉及到线程间通信. 关于线程间通信本文涉及到 ...
- Java中的守护线程和非守护线程(转载)
<什么是守护线程,什么是非守护线程> Java有两种Thread:"守护线程Daemon"(守护线程)与"用户线程User"(非守护线程). 用户线 ...
- 详解线程池的作用及Java中如何使用线程池
服务端应用程序(如数据库和 Web 服务器)需要处理来自客户端的高并发.耗时较短的请求任务,所以频繁的创建处理这些请求的所需要的线程就是一个非常消耗资源的操作.常规的方法是针对一个新的请求创建一个新线 ...
- 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法
[源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法 作者:webabcd 介绍重新想象 Wi ...
随机推荐
- 编程 MD(d)、MT(d)编译选项的区别
转:http://blog.csdn.net/nodeathphoenix/article/details/7550546 1.各个选项代表的含义 编译选项 包含 静态链接的lib 说明 /MD _M ...
- Gym 100299C && UVaLive 6582 Magical GCD (暴力+数论)
题意:给出一个长度在 100 000 以内的正整数序列,大小不超过 10^ 12.求一个连续子序列,使得在所有的连续子序列中, 它们的GCD值乘以它们的长度最大. 析:暴力枚举右端点,然后在枚举左端点 ...
- C++开发工程师面试题库 50~100道
51. New delete 与malloc free 的联系与区别?答案:都是在堆(heap)上进行动态的内存操作.用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对 ...
- python __builtins__ classmethod类 (11)
11.'classmethod', 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等. class cla ...
- bzoj 3224: Tyvj 1728 普通平衡树【非旋treap】
就是非旋treap的板子 #include<iostream> #include<cstdio> #include<cstdlib> using namespace ...
- Android中R.java丢失不见的解决方案
最近在做android项目时,遇到报错情况,于是clean了一下,结果java类全都报错了,里面的R下有红线,我一找,发现R.java不见了,真是奇怪,如下图(这是解决以后的): 然后查看了一下Con ...
- [SDOI2016]模式字符串
Description 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m的模式串s,其中每一位仍然是A到z的大写字母.Alice希望知道,有多 ...
- GDI双缓冲绘图
一.简介 在进行复杂图形绘制时,若直接在屏幕DC上进行绘制,则会出现明显的闪烁.闪烁产生的原因是当绘制的图形较为 复杂时,图形绘制过程中就被刷新到屏幕上,导致结果断断续续地显示出来.双缓冲绘图的原理是 ...
- org.codehaus.jettison.json.JSONObject使用方法
public static void main(String[] args) { System.out.println("测试开始"); File file = new File( ...
- C51之数据范围
在C51中各数据类型的范围如下:如果宏常量大于65536,则要加UL后缀:乘法运算不能只将结果强制类型转换,而应在被乘数前加(unsigned long)强制转换. 2 因为RAM有限,所以运算量大的 ...