程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> java 線程協作 join(),java線程協作join

java 線程協作 join(),java線程協作join

編輯:JAVA綜合教程

java 線程協作 join(),java線程協作join


個人理解,各位大牛請給指導勿噴。

為什麼會出現線程阻塞。

  1、當前任務(線程)需要使用另一個任務(線程)的執行結果時,這個時候我們要讓當前任務(線程)阻塞,等待另一個任務(線程)執行完畢,拿到他的處理結果再繼續執行。

  2、當多個線程同時訪問臨界區(共享資源)時,而該資源已經有線程占用。由於無法獲得相關的同步鎖,只好進入阻塞狀態,等到獲得了同步鎖,才能恢復運行。

什麼是線程阻塞

  所謂的阻塞,就是線程能夠運行,但是某個條件阻止它的運行,當線程處於阻塞狀態時,調度器將忽略線程,不會分配給線程任何CPU時間,直到線程重新進入就緒狀態,它才有可能執行操作。就緒並代表是在運行,所謂的就緒,就是可運行也可不運行,只有獲得調度器分配時間片,線程才可以運行。使線程阻塞的方法:

本文大綱:

一、join()

二、sleep()

三、yield()

四、wait();

join()

join() 方法主要是讓調用該方法的thread完成run方法裡面的任務後, 再執行join()方法後面的代。

主線程生成並起動了子線程,而子線程裡要進行大量的耗時的運算(這裡可以借鑒下線程的作用),當主線程處理完其他的事務後,需要用到子線程的處理結果,這個時候就要用到join();方法了。

 

//該方法會無限等待,它會一直阻塞當前線程直到目標線程(調用該方法的線程)執行完畢。   
public final void join() throws InterruptedException { join(0); }

 

//該方法需要給出最大等待時間,如果目標線程的執行時間超過給定的時間,那麼當前線程將不在等待目標線程執行結束而直接執行
public final synchronized void join(long millis)throws InterruptedException{}

 

public class ThreadJoinTest {
    private static String  str=null;
    public static void main(String[] args) {
        Thread thread=new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("進入"+Thread.currentThread().getName()+"線程");
                    Thread.sleep(1000);
                    str="hello Word";
                    System.out.println(Thread.currentThread().getName()+"線程業務處理完畢");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        thread.start();
        try {
            //thread.join();//設置main線程等待子線程先處理業務
            System.out.println(Thread.currentThread().getName()+"線程處理業務開始");
            System.out.println("獲取str值:"+str);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

執行結果:

main線程處理業務開始
進入Thread-0線程
獲取str值:null
Thread-0線程業務處理完畢

  運行代碼,貌似永遠都看不到str的值是"hello Word",而每次都是null,原因很簡單的,因為在thread中的run方法中對str進行賦值操作前休眠了1秒,此時main線程中的System.out.println方法已經執行了,所以很難看到str的值是"hello Word",為了看到str的值是"hello Word",我們的一個思路就是等thread運行結束之後,我們再執行System.out.println就可以了,這時候join方法的作用就顯現出來的,我們把上面的注釋代碼刪除注釋,然後運行,不管運行多少次,輸出的結果都是“hello Word”,從這個例子中我們就可以看到join方法的作用,它能夠調節各個線程之間的運行順序,從而可以實現同步。

  如果修改注釋的代碼為thread.join(100);則執行結果為:獲取str值:null ,因為主線程已經等不及了。

 

join()他讓調用線程在當前線程對象上進行等待當線程執行完畢後,被等待的線程會在推出前調用notifyAll()方法通知所有的等待線程繼續執行。

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

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved