博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java让主线程等待所有子线程执行完应该怎么做
阅读量:4058 次
发布时间:2019-05-25

本文共 2483 字,大约阅读时间需要 8 分钟。

深入理解java虚拟机中有这样一段代码

package AtomicTest;import java.util.concurrent.atomic.AtomicInteger;public class AtomicTest {    public static AtomicInteger race = new AtomicInteger(0);    public static void increase() {        race.incrementAndGet();    }    public static final int THREADS_COUNT = 5;    public static void main(String[] args) throws Exception {        Thread[] threads = new Thread[THREADS_COUNT];        for(int i = 0; i < THREADS_COUNT; i++) {            threads[i] = new Thread(new Runnable() {                @Override                public void run() {                    for(int i = 0; i < 10000; i++) {                        increase();                    }                }            });            threads[i].start();        }        while(Thread.activeCount() > 1) {            Thread.yield();        }        System.out.println(race);    }}

这段代码放到IDEA中会陷入死循环、为什么呢?因为在IDEA中有一个Monitor Ctrl-Break的线程来监听中断程序执行的信号、

改为 > 2就可以了。

可以使用Thread.enumerate()来打印出有哪些线程

Thread[] threads1 = new Thread[10];        int threadNum = Thread.enumerate(threads1);        for(int i = 0; i < threadNum; i++) {            System.out.println(threads1[i].getName());        }

 

但是我觉得使用join()更好。

但是join()不能乱用, 不能把join()放在创建线程的循环体内, 因为在执行join()的那一刻, 主线程会立即等待该线程执行完再继续执行下面的代码,

for(int i = 0; i < THREADS_COUNT; i++) {            threads[i] = new Thread(new Runnable() {                @Override                public void run() {                    try {                        Thread.sleep(10000);                    }catch (InterruptedException e) {                        e.printStackTrace();                    }                }            });            threads[i].start();            threads[i].join();            System.out.println("hello");        }

也就是如果按上面所写, 就是先开一个线程, 然后主线程等待该线程结束,打印hello, 然后再开一个线程, 主线程等待第二个线程结束, 再打印hello, 这样就变成串行执行了。完全没有并发的优势。为了验证这一点,我把线程任务设置为睡眠10s, 其执行结果就是每10s打印一次hello...

正确的写法:

for(int i = 0; i < THREADS_COUNT; i++) {            threads[i] = new Thread(new Runnable() {                @Override                public void run() {                    try {                        Thread.sleep(2000);                    }catch (InterruptedException e) {                        e.printStackTrace();                    }                }            });            threads[i].start();            System.out.println("hello");        }        for(int i = 0; i < THREADS_COUNT; i++) {            threads[i].join();        }

这样就会在2s时, 同时print 10个hello, 而不是每隔2s打印一个hello。

转载地址:http://hnzji.baihongyu.com/

你可能感兴趣的文章
慢慢欣赏linux phy驱动初始化2
查看>>
慢慢欣赏linux CPU占用率学习
查看>>
2020年终总结
查看>>
Homebrew指令集
查看>>
React Native(一):搭建开发环境、出Hello World
查看>>
React Native(二):属性、状态
查看>>
JSX使用总结
查看>>
React Native(四):布局(使用Flexbox)
查看>>
React Native(七):Android双击Back键退出应用
查看>>
Android自定义apk名称、版本号自增
查看>>
adb command not found
查看>>
Xcode 启动页面禁用和显示
查看>>
【剑指offer】q50:树中结点的最近祖先
查看>>
二叉树的非递归遍历
查看>>
【leetcode】Reorder List (python)
查看>>
【leetcode】Linked List Cycle (python)
查看>>
【leetcode】Linked List Cycle (python)
查看>>
【leetcode】Candy(python)
查看>>
【leetcode】Clone Graph(python)
查看>>
【leetcode】Sum Root to leaf Numbers
查看>>