天天看點

java多線程基礎知識

  在不是多線程的情況下,任務是一個一個執行的,然而當我們使用多線程的時候,cpu便允許單個程式建立多個并行執行的線程來完成各自的任務,這樣也就可以提高CPU的使用率。來初步認識下java中的多線程:

1、  java中的線程類繼承自java.lang.Thread或者其子類,Thread的構造函數有四個:

1、Thread();

2、Thread(String name);

3、Thread(Runnable target);

4、Thread(Runnable target,String name);

其中name是線程的名字,target是實作了Runnable接口的對象

2、線程類有以下成員函數:

1、void start();                                                         //啟動線程

2、static void sleep(long millis);                              //線程休眠millis毫秒 ,讓給其他任意優先級的線程

3、static void sleep(long millis,int nanos);              //millis毫秒naos納秒線程休眠

4、void join();                                                         //開始目前線程使其他線程停止直到目前線程終止

5、void join(long millis);                                         //開始目前線程使其他線程停止直到目前線程終止或者過去了millis毫秒

6、void join(long millis,int naonos);                      //同上 隻不過其他線程的等待時間變成millis毫秒 naosos納秒

7、static void yield();                                            //目前運作線程釋放處理器資源,讓給其他大于等于自己優先級的線程

8、static Thread currentThread();                         //傳回目前運作線程的引用

注意:sleep方法和yield方法都會暫停目前線程,但是sleep方法會将資源讓給其他線程而不關心它的優先級,但是yield方法則是讓給大于等于自己優先級的線程;

          sleep方法會将目前線程轉入阻塞狀态,直到阻塞之後才進入就緒狀态,然而yield則是使目前線程直接進入就緒狀态;

          sleep方法會抛出InterruptedException異常,而yield不會異常;

3、synchronized關鍵字          

synchronized關鍵字的作用是對一個對象或者是方法(其實還是持有這個方法的對象)加上鎖,加鎖實質上是取得對象的通路權限,如果對象已經被其他者所加鎖,那麼請求者就隻好進入等待隊列(休眠),知道被其他線程使用notify方法喚醒。在被加鎖的代碼塊當中,可能會出現一些情況,使得代碼需要一些條件才能繼續運作,此時為了讓這個代碼塊能夠被其他的線程執行到,必須釋放鎖,notify方法除了喚醒其他的線程,并把鎖交給它之外還有釋放鎖+讓自己休眠的作用。(notify在下面會介紹)

4、同步與互斥的代碼實作       

public class ThreadTest{
 private final Object lockObj=new Object();   //定義一把鎖
 public void todo(){
  synchronized(lockObj){	     //java使用synchronized關鍵字來實作互斥
   while(阻塞的條件){	    //在這裡阻塞的線程都會進入等待隊列
   try{
   	 lockObj.wait();	//條件不滿足時都會被阻擋 而不是競争資源
   }
   catch(InterruptedException e){
    	e.printStackTrace();
   }
}  
   //這裡寫上要進行的互斥代碼
   ...
   lockObj.notifyAll();//喚醒所有等待的線程 通知其他線程可以來競争資源了   
}
}
}
           

注意:wait()/notify()/notifyAll();這些都是Object的成員函數 而不是Thread的成員函數