一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 淺談Java線程Thread.join方法解析

淺談Java線程Thread.join方法解析

2021-03-19 11:55Ihesong Java教程

本篇文章主要介紹了淺談Java線程Thread.join方法解析,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

join字面上是加入的意思,我們先看看join方法的解釋和實現。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
   * Waits for this thread to die.
   * 調用方線程(調用join方法的線程)執行等待操作,直到被調用的線程(join方法所屬的線程)結束,再被喚醒
   * <p> An invocation of this method behaves in exactly the same
   * way as the invocation
   *
   *
   * @throws InterruptedException
   *     if any thread has interrupted the current thread. The
   *     <i>interrupted status</i> of the current thread is
   *     cleared when this exception is thrown.
   */
  public final void join() throws InterruptedException {
    join(0);
  }

這里join是調用的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
   * Waits at most {@code millis} milliseconds for this thread to
   * die. A timeout of {@code 0} means to wait forever.
   * 等待線程執行結束,或者指定的最大等待時間到了,調用方線程再次被喚醒,如果最大等待時間為0,則只能等線程執行結束,才能被喚醒。
   * <p> This implementation uses a loop of {@code this.wait} calls
   * conditioned on {@code this.isAlive}. As a thread terminates the
   * {@code this.notifyAll} method is invoked. It is recommended that
   * applications not use {@code wait}, {@code notify}, or
   * {@code notifyAll} on {@code Thread} instances.
   *
   *
   */
  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方法本身是通過wait方法來實現等待的,這里判斷如果線程還在運行中的話,則繼續等待,如果指定時間到了,或者線程運行完成了,則代碼繼續向下執行,調用線程就可以執行后面的邏輯了。

但是在這里沒有看到哪里調用notify或者notifyAll方法,如果沒有調用的話,那調用方線程會一直等待下去,那是哪里調用了喚醒它的方法呢?通過查證得知,原來在線程結束時,java虛擬機會執行該線程的本地exit方法,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//線程退出函數:
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
...
//這里會處理join相關的銷毀邏輯
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);
 
   //這里就調用notifyAll方法,喚醒等待的線程
   lock.notify_all(thread);
 
   thread->clear_pending_exception();
  }

這樣線程什么時候被喚醒就明白了。下面寫個例子看下效果。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class JoinTest {
  
  public static void main(String[] args) {
    
    ThreadBoy boy = new ThreadBoy();
    boy.start();
    
  }
  
  static class ThreadBoy extends Thread{
    @Override
    public void run() {
      
      System.out.println("男孩和女孩準備出去逛街");
      
      ThreadGirl girl = new ThreadGirl();
      girl.start();
      
      try {
        girl.join();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      
      System.out.println("男孩和女孩開始去逛街了");
    }
  }
  
  static class ThreadGirl extends Thread{
    @Override
    public void run() {
      int time = 5000;
      
      System.out.println("女孩開始化妝,男孩在等待。。。");
      
      try {
        Thread.sleep(time);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      
      System.out.println("女孩化妝完成!,耗時" + time);
      
    }
  }
  
}

執行結果為:

男孩和女孩準備出去逛街
女孩開始化妝,男孩在等待。。。
女孩化妝完成!,耗時5000
男孩和女孩開始去逛街了

就是男孩和女孩準備去逛街,女孩要化妝先,等女孩化妝完成了,再一起去逛街。

那join(time)的用法是怎么樣的呢?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class JoinTest {
  
  public static void main(String[] args) {
    
    ThreadBoy boy = new ThreadBoy();
    boy.start();
    
  }
  
  static class ThreadBoy extends Thread{
    @Override
    public void run() {
      
      System.out.println("男孩和女孩準備出去逛街");
      
      ThreadGirl girl = new ThreadGirl();
      girl.start();
      
      int time = 2000;
      try {
        girl.join(time);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      
      System.out.println("男孩等了" + time + ", 不想再等了,去逛街了");
    }
  }
  
  static class ThreadGirl extends Thread{
    @Override
    public void run() {
      int time = 5000;
      
      System.out.println("女孩開始化妝,男孩在等待。。。");
      
      try {
        Thread.sleep(time);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      
      System.out.println("女孩化妝完成!,耗時" + time);
      
    }
  }
  
}

這里僅僅把join方法換成了join(time)方法,描述改了點,打印的結果是:

男孩和女孩準備出去逛街
女孩開始化妝,男孩在等待。。。
男孩等了2000, 不想再等了,去逛街了
女孩化妝完成!,耗時5000

男孩等了join(time)中的time時間,如果這個time時間到達之后,女孩所在的線程還沒執行完,則不等待了,繼續執行后面的邏輯,就是不等女孩了,自己去逛街。

由此看出,join方法是為了比較方便的實現兩個線程的同步執行,線程1執行,碰到線程2后,等待線程2執行后,再繼續執行線程1的執行,加入的意思現在就比較形象化了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://www.jianshu.com/p/367fa66bf3f2

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 男人资源站 | 日本特级a禁片在线播放 | 水多多www视频在线观看高清 | 日本-区二区三区免费精品 日本破处 | 亚洲 欧美 国产 日韩 字幕 | 日本全黄三级在线观看 | ass极品美妇pic | 99久久国产亚洲综合精品 | 无人区1在线观看 | 国产四虎| 色国产精品 | 特级毛片全部免费播放器 | 青青青手机在线观看 | 91正在 播放 | 国产精品第一 | 久久sese | 国产在线视频欧美亚综合 | 国产福利不卡一区二区三区 | 精品免费国产一区二区三区 | 欧美高清在线不卡免费观看 | 息与子中文字幕完整在线 | 扒开女人屁股眼看个够 | 睡男神的这件小事小说在线阅读 | 久久国产精品永久免费网站 | 女性全身裸露无遮挡 | 狠狠干快播| 美女扒开屁股 | 秋霞一级黄色片 | 男女小视频在线观看 | 亚洲性色永久网址 | 国产精品久久久久久久久免费 | 97网站| 国产精品视频久久久久 | xxxx性欧美极品另类 | 99这里只有精品在线 | 日本大片免a费观看在线 | 成年人视频在线免费观看 | 男人躁女人p | 嫩草影院地址一地址二 | 舔比小说 | 欧美整片完整片视频在线 |