老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

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

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

創新互聯擁有一支富有激情的企業網站制作團隊,在互聯網網站建設行業深耕10年,專業且經驗豐富。10年網站優化營銷經驗,我們已為千余家中小企業提供了網站設計制作、網站設計解決方案,按需求定制網站,設計滿意,售后服務無憂。所有客戶皆提供一年免費網站維護!

/**
   * Waits for this thread to die.
   * 調用方線程(調用join方法的線程)執行等待操作,直到被調用的線程(join方法所屬的線程)結束,再被喚醒
   * 

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 * interrupted status of the current thread is * cleared when this exception is thrown. */ public final void join() throws InterruptedException { join(0); }

這里join是調用的

/**
   * Waits at most {@code millis} milliseconds for this thread to
   * die. A timeout of {@code 0} means to wait forever.
   * 等待線程執行結束,或者指定的最大等待時間到了,調用方線程再次被喚醒,如果最大等待時間為0,則只能等線程執行結束,才能被喚醒。
   * 

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方法,

//線程退出函數:
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();
  }

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

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)的用法是怎么樣的呢?

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的執行,加入的意思現在就比較形象化了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持創新互聯。


本文標題:淺談Java線程Thread.join方法解析
當前URL:http://www.xueling.net.cn/article/ihpcgs.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 超级av在线| 欧美一区二区三区免费在线看 | 国产成人精品三级麻豆 | 新婚少妇初尝禁果 | 超碰伊人久久 | 国产精品偷伦视频免费还看的 | 97人妻碰碰碰久久久久禁片 | 少妇的丰满3中文字幕 | 欧洲一级黄| 亚洲国产精品一区二区第四页 | 91久久久爱一区二区三区 | 午夜寂寞福利视频 | 最近中文字幕mv免费高清动漫 | 深夜福利在线播放 | 91精品乱码久久久久蜜桃 | 日日摸处处碰夜夜爽 | 日本免费一级高清婬日本片 | 亚洲精品拍拍央视网出文 | 99天天综合性 | 婷婷六月国产精品久久不卡 | 亚洲免费看片网站 | 国精产品一二二区视菠萝蜜 | 99久久精品午夜一区二区 | 中文字幕日韩精品欧美一区蜜桃网 | 精品欧美国产一区二区三区不卡 | 久久亚洲国产精品成人AV秋霞 | 在线观看免费视频一区 | 国内外免费激情视频 | 精品久久久久久无码免费 | 欧美成人性a片免费观看办公室 | 韓國三級大全久久網站 | 午夜免费看视频 | 久久精品人妻无码一区二区三区 | 第一页在线 | 最近2018中文字幕免费看手机 | 久久久国产精品亚洲一区 | 国产网站色 | 91福利在线视频 | 国产免费观看一区 | 国产精品美女一区二区三区四区 | 高清视频一区二区 |