谈谈对java线程的理解(二)--------关键字join

好了,上一篇我们已经初步了解了线程的创建与运行,那么下面我们来说说关键字 join

稍微熟悉java线程的伙伴都知道,Synchronized可以加锁,防止多线程对资源的抢占,提高数据的安全性等等。当然提起Synchronized,大家可能还会想起join ,wait,notify等等。

我们先说下提下join吧,这个单词大家都熟悉,意思是 成为…的一员; 参加; 加入;。

我们来看一个程序。

package com.example.thread;

public class MyThreadPool {

    public static void main(String[] args) throws Exception {

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程一开始"+Thread.currentThread());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程一结束"+Thread.currentThread());
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程二开始"+Thread.currentThread());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程二结束"+Thread.currentThread());
            }
        });
        System.out.println("main 方法开始。。。。"+Thread.currentThread());

        thread1.start();
        thread2.start();

//        thread1.join();
//        thread2.join();
        System.out.println("main 方法结束。。。。"+Thread.currentThread());
    }

}

下面我们看下运行结果:

main 方法开始。。。。Thread[main,5,main]
main 方法结束。。。。Thread[main,5,main]
线程一开始Thread[Thread-0,5,main]
线程二开始Thread[Thread-1,5,main]
线程一结束Thread[Thread-0,5,main]
线程二结束Thread[Thread-1,5,main]

Process finished with exit code 0

这个没什么问题,主线程加两个线程启动,然后多线程运行,互不影响,线程一和线程二启动需要时间,所以主线程先结束了。然后线程一和线程二启动,等待5秒明显会最后结束。

那如果加上了join呢?我们看下运行结果:

main 方法开始。。。。Thread[main,5,main]
线程二开始Thread[Thread-1,5,main]
线程一开始Thread[Thread-0,5,main]
线程二结束Thread[Thread-1,5,main]
线程一结束Thread[Thread-0,5,main]
main 方法结束。。。。Thread[main,5,main]

我們來看下,主线程先启动是没有任何问题的,然后线程一和线程二启动了,它们相隔太短,又互不影响,所以开始的时候不一定哪个先输出,但是一定在main方法前先结束的。为什么呢?join!因为线程一和线程二调用了join方法!

我们来看下这个程序的运行,首先,三个线程启动,互不影响(join方法未调用之前),然后线程一和线程二都调用了join,首先线程一调用了join,线程一就夹在main线程开始于结束之间,然后线程二又调用join,也插队到了中间,所以线程二和线程一的方法先运行完。

那为什么呢?

大家来看下join()的源码:

 public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

从代码中,我们可以发现。当millis==0时,会进入while( isAlive() )循环;即只要子线程是活的,主线程就不停的等待。

所以线程一和线程二实际上是抢占了main方法的资源,插队到了前面,自然会先运行完。

好了,今天就先到这里,明天再补上Synchronize吧【笑哭】

 

no sacrifice,no victory!!!

猜你喜欢

转载自blog.csdn.net/zsah2011/article/details/107922351