码迷,mamicode.com
首页 > 编程语言 > 详细

java多线程-join

时间:2018-12-14 12:55:31      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:final   线程   locker   exception   test   参数   on()   xtend   sse   

之前看了一些博客说join就是把多线程变成单线程,其实并不是,执行join还是多线程。

class Test {
    public static void main(String[] args) throws InterruptedException {
        TestJoin t0 = new TestJoin();
        TestJoin t1 = new TestJoin();
        t0.start();
        t1.start();
        t0.join();
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }
}

class TestJoin extends Thread{
    @Override
    public void run(){
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }
}
/**
 结果:t0.t1线程交替打印至t0执行结束,然后开始t1,main线程交替打印。
 */

结合源码看看join做了什么。

public final void join() throws InterruptedException {
        join(0);
}
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;
            }
        }
    }

执行过程(这里讨论执行无参join方法,如果执行有参数join(xx),其实就是让main线程wait(xx)):

  1. main线程执行t0.join()。
  2. main线程执行join(),join()执行join(0),join(long millis)是一个同步方法。
  3. while(isAlive)这里的isAlive是t0的isAlive,如果t0存活,此时main线程持有t0的对象锁,执行wait。 (while确保了其他线程持有t0锁执行notifyAll后也无法唤醒main线程)
  4. main线程进入WAITING状态。
  5. t0,t1状态正常,交替执行至t0结束。
  6. t0结束后,由本地方法执行t0.notifyAll,main线程被唤醒。(源码中并看不到如何notifyAll的,线程结束后会执行一个本地方法notifyAll)
  7. 这时如果t1还没执行完成,main和t1交替执行。

https://blog.csdn.net/erica_1230/article/details/69388742 中介绍了:线程结束时调用的本地方法notifyAll

static void ensure_join(JavaThread* thread) {
  Handle threadObj(thread, thread->threadObj());
  assert(threadObj.not_null(), "Java thread object must exist");
  ObjectLocker lock(threadObj, thread);
  thread->clear_pending_exception();
  java_lang_Thread::set_stillborn(threadObj());
  java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
  java_lang_Thread::set_thread(threadObj(), NULL);
  lock.notify_all(thread);
  thread->clear_pending_exception();
}

 

结论:当一个线程a执行线程b.join()则,线程a等待至线程b执行完毕后继续执行,这个过程并不影响其线程的执行。

java多线程-join

标签:final   线程   locker   exception   test   参数   on()   xtend   sse   

原文地址:https://www.cnblogs.com/liuboyuan/p/10118236.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!