多線程知識點2

一、Thread類中常用方法

1、Thread類的常用靜態方法:

    ①、static Thread currentThread(); 返回對當前正在執行的線程對象的引用。
    ②、static void sleep(long millis) throws InterruptedException 讓當前正在執行的線程休眠(暫停執行),
    休眠時間millis(毫秒)指定。
    ③、static void sleep(long millis,int nanos) throws InterruptedException 讓當前正在執行的線程休眠,
    休眠時間由millis(毫秒)和nanos(納秒)指定。
    ④、static void yield(); 暫停當前正在執行的線程,轉而執行其他線程.
    ⑤、static boolean interrupted(); 


2、Thread類的常用構造方法:

   ①、Thread() 創建一個新線程
   ②、Thread(String name) 創建一個指定名稱的線程
   ③、Thread(Runnable target) 利用 Runnable 對象創建一個線程,啓動時將執行該對象的 run 方法
   ④、Thread(Runnable target, String name) 利用 Runnable 對象創建一個線程,並指定該線程的名稱


3、Thread類的其它常用方法:

    ①、void start() 啓動線程
    ②、final void setName(String name) 設置線程的名稱
    ③、final String getName() 返回線程的名稱
    ④、final void setPriority(int newPriority) 設置線程的優先級
    ⑤、final int getPriority() 返回線程的優先級

    

4、與線程相關的一些方法:


    ①、final void join()throws InterruptedException 等待線程終止
    ②、final boolean isAlive() 判斷線程是否處於活動狀態

    ③、void interrupted() 中斷線程

    ④、sleep、yield和join:
    
    sleep和yield都是Thread類的靜態方法,都會使當前處於運行狀態的線程放棄CPU,但兩者的區別在於:
sleep給其它線程運行的機會,但不考慮其它線程的優先級;但yield只會讓位給相同或更高優先級的線程;
當線程執行了sleep方法後,將轉到阻塞狀態,而執行了yield方法之後,則轉到就緒狀態;
sleep方法有可能拋出異常,而yield則沒有;在一般情況下,我們更建議使用sleep方法。
join方法用於等待其它線程結束,當前運行的線程可以調用另一線程的join方法,當前運行線程將轉到阻塞狀態,        直至另一線程執行結束,它纔會恢復運行。


  1)、sleep用法:
  Thread.sleep(long millis)和 Thread.sleep(long millis, int nanos) 靜態方法強制當前正在執行的線程休眠
 (暫停執行),以“減慢線程”。當線程睡眠時,它入睡在某個地方,在甦醒之前不會返回到可運行狀態。當睡               眠時間到期,則返回到可運行狀態。

①、線程睡眠的原因:線程執行太快,或者需要強制進入下一輪

②、睡眠的實現:調用靜態方法。

try {

Thread.sleep(1000);

}catch (InterruptedException e){

e.printStackTrace();
  }
  
③、睡眠的位置:爲了讓其他線程有機會執行,可以將Thread.sleep()的調用放線程run()之內。這樣才能保證該                線程執行過程中會睡眠。
④、線程睡眠是幫助所有線程獲得運行機會的最好方法。
⑤、線程睡眠到期自動甦醒,並返回到可運行狀態,不是運行狀態。sleep()中指定的時間是線程不會運行的最短                時間。因此,sleep()方法不能保證該線程睡眠到期後就開始執行。sleep()是靜態方法,只能控制當前正在運                行的線程。


  2)、yield的用法:
  
   ①、Thread.yield() 方法的作用是:暫停當前正在執行的線程對象,並執行其他線程,讓相同優先級的線程之間能適           當的輪轉執行。
   ②、yield() 做的是讓當前運行線程回到可運行狀態,以允許具有相同優先級的其他線程獲得運行機會。但是,實際             中無法保證 yield() 達到讓步目的,因爲讓步的線程還有可能被線程調度程序再次選中。
   ③、結論:yield() 從未導致線程轉到等待/睡眠/阻塞狀態。在大多數情況下,yield() 將導致線程從運行狀態轉到可             運行狀態,但有可能沒有效果。


  3)、join的用法:
  
    Thread 的非靜態方法 join() 讓一個線程B“加入”到另外一個線程A的尾部。在A執行完畢之前,B不能工作。
    常用於主線程需要用到子線程執行完後的結果,即主線程需要等待子線程執行完成後再結束。
    

   例:創建並啓動線程t,加入到當前運行的線程中

MyThread t = new MyThread();
t.start();
t.join();
 
 
5、與後臺線程相關的方法:


①、final void setDaemon(boolean on) 將該線程設置爲後臺線程
②、final boolean isDaemon() 判斷該線程是否爲後臺線程
  注意:要將某個線程設置爲後臺線程的話,必須在它啓動之前調用 setDeamon 方法;
          默認情況下,由前臺線程創建的線程仍是前臺線程,由後臺線程創建的線程仍是後臺線程。
   


當多個線程共享數據時,往往可能發生數據讀寫不一致的情況,這時候就需要使用同步


1、線程同步的概念
①、線程是一份獨立運行的程序,有自己專用的運行棧。線程有可能和其他線程共享一些資源,比如,內存,                   文件,數據庫等

②、多個線程同時讀寫同一份共享資源時,可能會引起衝突。所以引入線程“同步”機制,即各線程間要有先來後                 到;

③、同步就是排隊:幾個線程之間要排隊,一個一個對共享資源進行操作,而不是同時進行操作;


2、實現線程同步的方式
   確保一個時間點只有一個線程訪問共享資源。可以給共享資源加一把鎖,這把鎖只有一把鑰匙。哪個線程獲取了這      把鑰匙,纔有權利訪問該共享資源。

在Java代碼中實現同步要完成以下兩步:
 ①、把競爭訪問的資源標識爲 private
 ②、使用 synchronized(同步的) 關鍵字同步方法或代碼塊。

 
3、synchronized關鍵字的使用:


   1)、同步的方法:
     ①、使用 synchronized 修飾的方法:
     
             訪問修飾符 synchronized 數據返回類型 方法名(){
             
                   ......
                   
              }



     ②、它鎖定的是調用這個同步方法的對象。其它線程不能同時訪問這個對象中任何一個 synchronized 方法。


     ③、不同的對象實例的 synchronized 方法是不相干擾的。其它線程照樣可以同時訪問相同類的另一個對象實例中             的 synchronized 方法。


     使用同步方法,可以方便的將類變成線程安全的類。


     防止多個線程同時訪問這個類中的 synchronized static 方法。它可以對類的所有對象實例起作用。
    
       訪問修飾符 synchronized static 數據返回類型 方法名(){
       
                  ......
         
         }


   2)、同步語句塊
        只對這個區塊的資源實行互斥訪問:
        
     synchronized(共享對象名){ 
     
        被同步的代碼段
       
      }

       
    它鎖定的是共享對象名對應的當前對象。
    線程中實現同步塊一般是在 run 方法中添加。
    如果沒有明確的對象作爲鎖,只想讓一塊代碼同步時,可以創建一個特殊的實例變量:
    
           /*特殊的實例變量
  (零長度的byte數組對象創建起來將比任何對象都經濟)*/
  
  private byte[] lock = new byte[0];
  
  synchronized(lock){
 
      被同步的代碼段
      
  }


4、線程同步的注意事項


 ①、不要對線程安全類的所有方法都進行同步,只對那些會改變共享資源方法的進行同步。同步塊越大,多線                    程的效率越低

 ②、synchronized 關鍵字可以修飾方法,也可以修飾代碼塊,但不能修飾構造器、抽象方法、成員屬性等。

 ③、synchronized 關鍵字是不能繼承的。

 ④、無論 synchronized 關鍵字加在方法上還是對象上,它取得的鎖都是對象,而不是把一段代碼或函數當作                       鎖。


 ⑤、搞清楚 synchronized 鎖定的是哪個對象。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章