Java中线程同步(一):join

第一类: join、wait¬ify
第二类:Synchronized、ReentrantLock、ReentrantReadWriteLock、Condition 、StampedLock
第三类:Semaphore、CountDownLatch、CyclicBarrier

上面是涉及到线程间通讯的一些方法或者类,这里做一下整理,说到线程间同步,就少不了一个关键字 volatile,它的作用是保证变量在各个线程之间保持同步,如果你读过Android系统关于线程池的源码,你就会发现在系统定义好的几个线程池类中都会使用volatile关键字来修饰全局变量。

第一类是靠线程自身提供的一些方法来保证线程间的同步行为,比较简单。
join:join是保持线程同步的一种方式,你可以把它简单的理解为插队。比如说现在我们有两个任务A和B需要执行,但是在执行任务A的过程中需要等待任务B执行完成之后才能继续执行。这个时候使用join关键字就比较合适,就好比说任务B插队到任务A的前面,只有等任务B完成了之后任务A才能继续执行。

不使用关键字join和使用join关键字的程序运行图比较
Java中线程同步(一):join_第1张图片
图1:无join,异步

Java中线程同步(一):join_第2张图片
图2: 有join,同步

新建两个线程ThreadA和ThreadB,运行代码测试看结果

     @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //程序入口(我这里是一个Android程序中的Fragment的入口)
        //如果是Java程序,只需将这个两句放到main方法中即可
        mThreadA = new ThreadA();
        mThreadA.start();
    }

    private class ThreadA extends Thread {
        @Override
        public void run() {
            super.run();
            Log.e(TAG, "A start");
            try {
                ThreadB mThreadB = new ThreadB();
                mThreadB.start();
//                mThreadB.join();//打开注释就是使用join关键字
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, "A " + e.toString());
            }
            Log.e(TAG, "A end");
        }
    }

    private class ThreadB extends Thread {
        @Override
        public void run() {
            super.run();

            Log.e(TAG, "B start");
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, "B " + e.toString());
            }
            Log.e(TAG, "B end");
        }
    }

上面的代码运行之后,控制台输出

03-02 15:35:57.054 5345-5392/? E/ThreadRun: A start
03-02 15:35:57.055 5345-5392/? E/ThreadRun: A end
03-02 15:35:57.055 5345-5393/? E/ThreadRun: B start
03-02 15:35:58.056 5345-5393/? E/ThreadRun: B end

与图1相符。
找到代码中 // mThreadB.join();取消注释,再次运行,控制台输出

03-02 16:34:16.131 6793-6825/? E/ThreadRun: A start
03-02 16:34:16.132 6793-6828/? E/ThreadRun: B start
03-02 16:34:17.132 6793-6828/? E/ThreadRun: B end
03-02 16:34:17.133 6793-6825/? E/ThreadRun: A end

与图2相符。
这就是一个简单的使用join关键字保持线程同步的例子。

你可能感兴趣的:(Java中线程同步(一):join)