Thread.join 解析

版权声明:作者:N3verL4nd 出处: https://blog.csdn.net/lgh1992314/article/details/80070515
/**                                                                                     
 * Waits at most {@code millis} milliseconds for this thread to                         
 * die. A timeout of {@code 0} means to wait forever.                                   
 * 等待该线程终止的时间最长为 millis 毫秒
 * millis 为 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()) {                                      
            // 使调用 join 方法的线程(持有该线程对象的锁)进入阻塞状态(WAITING)
            wait(0);                                        
        }                                                                
    } else {
        // 有时间等待,如果当前线程还没有结束,则不再等待
        while (isAlive()) {                                              
            long delay = millis - now;                                   
            if (delay <= 0) {                                            
                break;                                                   
            }
            // // 使调用 join 方法的线程(持有该线程对象的锁)进入阻塞状态(TIMED_WAITING)            
            wait(delay);                                                 
            now = System.currentTimeMillis() - base;                     
        }                                                                
    }                                                                    
}                                                                                                                                                            

/**
 * 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒                                                     
 */                                                                                     
public final synchronized void join(long millis, int nanos)                             
throws InterruptedException {                                                           

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

    if (nanos < 0 || nanos > 999999) {                                                  
        throw new IllegalArgumentException(                                             
                            "nanosecond timeout value out of range");                   
    }                                                                                   

    if (nanos >= 500000 || (nanos != 0 && millis == 0)) {                               
        millis++;                                                                       
    }                                                                                   

    join(millis);                                                                       
}                                                                                       

/**                                                                                     
 * 等待该线程终止                                                    
 * 等价于调用: join(0)                                                             
 * 如果任何线程中断了当前线程,则抛出 InterruptedException 异常 
 * 当抛出该异常时,当前线程的中断状态 被清除。
 */                                                                                     
public final void join() throws InterruptedException {                                  
    join(0);                                                                            
}                                                                                       

对于 synchronized(无论是作为方法的修饰符还是作为一个语句):哪个线程正在执行这个方法,就是哪个线程获取这个锁。

既然 join 方法的实现是wait,那么必然会有调用notify。这是JVM替我们调用的。

作者:cao
链接:https://www.zhihu.com/question/44621343/answer/97640972
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

//一个c++函数:
void JavaThread::exit(bool destroy_vm, ExitType exit_type) ;

//这家伙是啥,就是一个线程执行完毕之后,jvm会做的事,做清理啊收尾工作,
//里面有一个贼不起眼的一行代码,眼神不好还看不到的呢,就是这个:

ensure_join(this);

//翻译成中文叫 确保_join(这个);代码如下:

static void ensure_join(JavaThread* thread) {
  Handle threadObj(thread, thread->threadObj());

  ObjectLocker lock(threadObj, thread);

  thread->clear_pending_exception();

  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();
}

举个栗子:

import java.util.concurrent.TimeUnit;

public class Main1 {
    public static void main(String[] args) {
        Thread thread = new Thread(() ->{
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                System.out.println(i);
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.exit(-1);
    }
}

假设没有调用thread.join();,则 thread 线程没有输出。
咦,这不就是 Junit 不支持多线程测试的解决方案么?=。=
https://blog.csdn.net/x_iya/article/details/77877897

猜你喜欢

转载自blog.csdn.net/lgh1992314/article/details/80070515
今日推荐