java thread join

来源:互联网 发布:qq飞车改装30雷诺数据 编辑:程序博客网 时间:2024/06/08 19:53

java多线程编程join的作用是等待线程结束,这个作用可以产生很多特定的场景。
1)A线程中调用B线程的join方法,那么A线程需要等待B线程执行完成后才能完成
2)主线程中依次调用A线程的join方法,B线程的join方法,可以保证A,B线程顺序执行;当主线程需要等待多个线程完成后再继续执行时,join方法可能会产生迷惑作用,虽然这个时候主线程等到了多个线程的完成,但是这时多个线程的执行并不是并发执行的,要解决这个问题,可以采用CountdownLatch来完成,CountdownLatch是线程流程控制方式的一种,另外一种是CycliBarrier,它具有等待多个线程完成时,执行一个线程的功能,这样也可以满足等待的需求。

下面是一个使用join的错误情况:

public class NoSafe {    public static void main(String argv[]) {        final List<String> list = new ArrayList<String>();        for (int i = 0; i < 10; i++) {            Thread t = new Thread("Thread"+i) {                public void run() {                    System.out.println(Thread.currentThread().getName() + " Start!");                    for (int i = 0; i < 100; i++) {                        list.add(String.valueOf(i));                    }                }            };            t.start();            try {                t.join();            } catch (Exception e) {                e.printStackTrace();            }        }        System.out.println(list.size());    }}

上面例子中实际上多个线程是顺序执行的,并没有并发执行,因此对ArrayList的使用没有抛出任何的异常,当我们去掉join之后再次执行,情况就不一样了,这个时候会产生意想不到的异常,比如ArrayIndexOutOfBoundsException等,我们可以尝试将ArrayList换成LinkedList来查看执行结果,这个时不会产生异常,但是数据量不对,最终的size不是1000。试着将list换成CopyOnWriteArrayList然后再来运行看看结果。这个时候没有异常,数据量也是正确的。
当然了,为了等待最终的结果,我们必须想办法让主线程等待所有线程执行结束,这里为了测试的话,可以在输出结果之前在主线程中添加Sleep达到这个目的,当然最好的实现还是使用流程控制的方法,比如CountDownLatch或者CycliBarrier。

0 0