欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2018年01月13日 11:10:32   作者:Ihesong  
本篇文章主要介紹了淺談Java線程Thread.join方法解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

join字面上是加入的意思,我們先看看join方法的解釋和實(shí)現(xiàn)。

/**
   * Waits for this thread to die.
   * 調(diào)用方線程(調(diào)用join方法的線程)執(zhí)行等待操作,直到被調(diào)用的線程(join方法所屬的線程)結(jié)束,再被喚醒
   * <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是調(diào)用的

/**
   * Waits at most {@code millis} milliseconds for this thread to
   * die. A timeout of {@code 0} means to wait forever.
   * 等待線程執(zhí)行結(jié)束,或者指定的最大等待時(shí)間到了,調(diào)用方線程再次被喚醒,如果最大等待時(shí)間為0,則只能等線程執(zhí)行結(jié)束,才能被喚醒。
   * <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方法本身是通過(guò)wait方法來(lái)實(shí)現(xiàn)等待的,這里判斷如果線程還在運(yùn)行中的話,則繼續(xù)等待,如果指定時(shí)間到了,或者線程運(yùn)行完成了,則代碼繼續(xù)向下執(zhí)行,調(diào)用線程就可以執(zhí)行后面的邏輯了。

但是在這里沒(méi)有看到哪里調(diào)用notify或者notifyAll方法,如果沒(méi)有調(diào)用的話,那調(diào)用方線程會(huì)一直等待下去,那是哪里調(diào)用了喚醒它的方法呢?通過(guò)查證得知,原來(lái)在線程結(jié)束時(shí),java虛擬機(jī)會(huì)執(zhí)行該線程的本地exit方法,

//線程退出函數(shù):
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
...
//這里會(huì)處理join相關(guān)的銷毀邏輯
ensure_join(this);
...
}
//處理join相關(guān)的銷毀邏輯
  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);

   //這里就調(diào)用notifyAll方法,喚醒等待的線程
   lock.notify_all(thread);

   thread->clear_pending_exception();
  }

這樣線程什么時(shí)候被喚醒就明白了。下面寫(xiě)個(gè)例子看下效果。

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("男孩和女孩準(zhǔn)備出去逛街");
      
      ThreadGirl girl = new ThreadGirl();
      girl.start();
      
      try {
        girl.join();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      
      System.out.println("男孩和女孩開(kāi)始去逛街了");
    }
  }
  
  static class ThreadGirl extends Thread{
    @Override
    public void run() {
      int time = 5000;
      
      System.out.println("女孩開(kāi)始化妝,男孩在等待。。。");
      
      try {
        Thread.sleep(time);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      
      System.out.println("女孩化妝完成!,耗時(shí)" + time);
      
    }
  }
  
}

執(zhí)行結(jié)果為:

男孩和女孩準(zhǔn)備出去逛街
女孩開(kāi)始化妝,男孩在等待。。。
女孩化妝完成!,耗時(shí)5000
男孩和女孩開(kāi)始去逛街了

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

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

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("男孩和女孩準(zhǔn)備出去逛街");
      
      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("女孩開(kāi)始化妝,男孩在等待。。。");
      
      try {
        Thread.sleep(time);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      
      System.out.println("女孩化妝完成!,耗時(shí)" + time);
      
    }
  }
  
}

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

男孩和女孩準(zhǔn)備出去逛街
女孩開(kāi)始化妝,男孩在等待。。。
男孩等了2000, 不想再等了,去逛街了
女孩化妝完成!,耗時(shí)5000

男孩等了join(time)中的time時(shí)間,如果這個(gè)time時(shí)間到達(dá)之后,女孩所在的線程還沒(méi)執(zhí)行完,則不等待了,繼續(xù)執(zhí)行后面的邏輯,就是不等女孩了,自己去逛街。

由此看出,join方法是為了比較方便的實(shí)現(xiàn)兩個(gè)線程的同步執(zhí)行,線程1執(zhí)行,碰到線程2后,等待線程2執(zhí)行后,再繼續(xù)執(zhí)行線程1的執(zhí)行,加入的意思現(xiàn)在就比較形象化了。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java將RTF轉(zhuǎn)換為PDF格式的實(shí)現(xiàn)

    Java將RTF轉(zhuǎn)換為PDF格式的實(shí)現(xiàn)

    本文主要介紹了Java將RTF轉(zhuǎn)換為PDF格式的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 帶有@Transactional和@Async的循環(huán)依賴問(wèn)題的解決

    帶有@Transactional和@Async的循環(huán)依賴問(wèn)題的解決

    這篇文章主要介紹了帶有@Transactional和@Async的循環(huán)依賴問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • SpringBoot中的配置類(@Configuration)

    SpringBoot中的配置類(@Configuration)

    這篇文章主要介紹了SpringBoot中的配置類(@Configuration),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Spring Security 自定義資源服務(wù)器實(shí)踐過(guò)程

    Spring Security 自定義資源服務(wù)器實(shí)踐過(guò)程

    這篇文章主要介紹了Spring Security 自定義資源服務(wù)器實(shí)踐,我們通過(guò)自己搭建的授權(quán)服務(wù)器和資源服務(wù)器,完整體驗(yàn)了OAuth2流程,需要的朋友可以參考下
    2022-08-08
  • Elasticsearch寫(xiě)入瓶頸導(dǎo)致skywalking大盤(pán)空白

    Elasticsearch寫(xiě)入瓶頸導(dǎo)致skywalking大盤(pán)空白

    這篇文章主要為大家介紹了Elasticsearch寫(xiě)入瓶頸導(dǎo)致skywalking大盤(pán)空白的解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • spring boot實(shí)現(xiàn)圖片上傳和下載功能

    spring boot實(shí)現(xiàn)圖片上傳和下載功能

    這篇文章主要為大家詳細(xì)介紹了spring boot實(shí)現(xiàn)圖片上傳和下載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Spring?緩存在項(xiàng)目中的使用詳解

    Spring?緩存在項(xiàng)目中的使用詳解

    Spring?緩存機(jī)制,Cache接口為緩存的組件規(guī)范定義,包擴(kuò)緩存的各種操作(添加緩存、刪除緩存、修改緩存等),本文給大家介紹Spring?緩存在項(xiàng)目中的使用,感興趣的朋友一起看看吧
    2025-05-05
  • spring+springmvc整合mabytis時(shí)mapper注入失敗問(wèn)題解決方法

    spring+springmvc整合mabytis時(shí)mapper注入失敗問(wèn)題解決方法

    這篇文章主要介紹了spring+springmvc整合mabytis時(shí)mapper注入失敗問(wèn)題解決方法 ,需要的朋友可以參考下
    2017-08-08
  • Java中的Redis是什么意思

    Java中的Redis是什么意思

    Redis是一個(gè)非常強(qiáng)大的工具,它可以用來(lái)實(shí)現(xiàn)很多有趣的應(yīng)用,還可以使用Redis來(lái)實(shí)現(xiàn)分布式鎖,這樣你就可以在多線程或多進(jìn)程的環(huán)境下同步代碼,這篇文章主要介紹了Java中的Redis是什么意思,需要的朋友可以參考下
    2023-08-08
  • java自帶排序使用

    java自帶排序使用

    這篇文章主要給大家分享了java自帶排序使用,該方法是升序排序,方法的內(nèi)部采用了快排實(shí)現(xiàn),但該方法是?穩(wěn)定的。下面一起來(lái)看看文章的詳細(xì)介紹吧
    2021-12-12

最新評(píng)論