python的threading.Thread線程的start、run、join、setDaemon


Pycharm整體看下Thread類的內容:模擬的是Java的線程模型

 

表示方法method,上面的鎖頭表示這個是類內部的方法,從方法名字命名規范可以看出,都是_和__開頭的,一個下划線表示是子類可以繼承,兩個下划線表示是只有Thread內部可以訪問,子類都不可以訪問。

表示property,可以使用類直接訪問:Thread._block

表示field,就是self.x定義的東東

 

表示變量variable

name/getName/setName是線程名字有關的;

isDaemon是否是守護進程
setDaemon設置為守護進程,如果把調用線程設置為守護線程,那么等調用線程結束后,被調用的子線程結束與否都會隨着守護線程結束

 

 
        
isAlive線程是否是活動狀態

start方法開啟一個新線程。把需要並行處理的代碼放在run()方法中,start()方法啟動線程將自動調用 run()方法。

 

 
        
run線程實際在運行的內容,可以被子類繼承和重寫overide。

 

 
        
join阻塞調用它的線程,直到等待被調用的線程運行結束,其實就變成了單線程。參數timeout的作用是,當前線程等待被調用的子線程的時間,如果時間到了,不管子線程是否結束,當前線程都進入就緒狀態,重新等待CPU調度。

 

Join方法的Java示例:

新建一個Thread類,重寫run()方法:

public class MyThread extends Thread {

    @Override
    public void run() {
        System.out.println("子線程執行完畢");
    }
}

新建測試類,測試Join()方法:

public class TestThread {

    public static void main(String[] args) {
        //循環五次
        for (int i = 0; i < 5; i++) {

            MyThread thread = new MyThread();
            //啟動線程
            thread.start();
            try {
                //調用join()方法
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("主線程執行完畢");
            System.out.println("~~~~~~~~~~~~~~~");

        }
    }
}

輸出結果如下:

子線程執行完畢
主線程執行完畢
~~~~~~~~~~~~~~~
子線程執行完畢
主線程執行完畢
~~~~~~~~~~~~~~~
子線程執行完畢
主線程執行完畢
~~~~~~~~~~~~~~~
子線程執行完畢
主線程執行完畢
~~~~~~~~~~~~~~~
子線程執行完畢
主線程執行完畢
~~~~~~~~~~~~~~~

結果分析: 子線程每次都在主線程之前執行完畢,即子線程會在主線程之前執行。

 
        
 
        

 

 

什么時候用join()方法?
  在很多情況下,主線程生成並起動了子線程,如果子線程里要進行大量的耗時的運算,主線程往往將於子線程之前結束,但是如果主線程處理完其他的事務后,需要用到子線程的處理結果,也就是主線程需要等待子線程執行完成之后再結束,這個時候就要用到join()方法了。
  用start方法來啟動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。通過調用Thread類的start()方法來啟動一個線程,這時此線程處於就緒(可運行)狀態,並沒有運行,一旦得到cpu時間片,就開始執行run()方法,這里方法 run()稱為線程體,它包含了要執行的這個線程的內容,run方法運行結束,此線程隨即終止。
  run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是只有一條,還是要順序執行,還是要等待run方法體執行完畢后才可繼續執行下面的代碼,這樣就沒有達到寫線程的目的。

  總結:調用start方法方可啟動線程,而run方法只是thread的一個普通方法調用,還是在主線程里執行。把需要並行處理的代碼放在run()方法中,start()方法啟動線程將自動調用 run()方法

可見join和setDaemon作用是相反的,一個是等待子線程結束,一個是不等到子線程結束,有可能把子線程強制結束。如果兩個都不設置的時候,那么主線程和子線程各自運行各自的,互不干擾,誰結束都不會影響另一個運行情況:見https://www.cnblogs.com/alan-babyblog/p/5325071.html示例

 

 

參考:

1、https://blog.csdn.net/earthchinagl/article/details/72771126

2、https://juejin.im/post/5b3054c66fb9a00e4d53ef75

3、https://www.cnblogs.com/alan-babyblog/p/5325071.html

 
        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM