java執行緒學習

以神之諭發表於2015-12-12

  1.  執行緒是程式中的一條執行路徑,即程式的執行流程。
  2.  多執行緒即程式中包含多條執行路徑,指一個程式中可以同時執行多個程式塊。多執行緒程式設計就是將程式任務分成幾個並行的小任務,多個執行緒可以共享一塊記憶體區域和資源。
  3. 執行緒的5個基本狀態:建立狀態;就緒狀態;執行狀態;阻塞狀態;終止狀態。
  4. 建立狀態: 用new運算子建立Thread或者其子類的例項化物件,新執行緒即處於建立狀態。例如:   new Thread(子類物件名).start();  new Thread(子類物件名).start();  就建立了兩個執行緒。
  5. 就緒狀態:呼叫start()方法,具有執行條件。即為執行緒分配系統資源,執行緒啟動並進入就緒狀態,進入執行緒佇列排隊,等待cpu服務,一旦獲得CPU等資源,就可以脫離其主執行緒獨立執行。
  6. 執行狀態:run();
  7. 阻塞狀態: 以下4種情況都是執行緒會進入阻塞狀態。 阻塞時,執行緒不能進入排隊佇列,只有消除阻塞後才可以轉入到就緒狀態。
    • 呼叫sleep();
    • wait();
    • suspend();
    • 該執行緒正在等待I/O操作。
  8. 終止狀態:stop(),destroy()方法。                 
  9. 建立執行緒的兩種方式:
  • 繼承Thread類。
    public class 類名稱 extends Thread{//從Thread類擴充套件出子類
    	public 類名稱(){
    		//子類的構造方法
    	}
    	public void run(){
    		//重寫Thread類裡的run()方法。
    	}
    	public static void mian(String args[]){
    		子類類名稱 物件名=new 子類類名稱();
    		子類的物件.start();
    				
    	}
    }
  • 實現Runnable介面。
    //實現Runnabel介面建立執行緒的方式
    class ManyThread implements Runnable {
    	//屬性
    	//方法
    	public ManyThread(){
    		//構造方法
    	}
    	public void run(){
    		//執行緒的功能程式碼
    	}
    	public static void main(String[] args) {
    		ManyThread rs=new ManyThread();
    		Thread t=new Thread(rs);
    		t.start();
    		
    	}
    }
    當Java想要繼承某個類的同時建立多執行緒的時候,就需要用Runable介面建立執行緒了。    
  1. 程式與執行緒:程式:一個任務就是一個程式。作業系統中,程式被看做是系統資源的分配單位和獨立執行的基本單位。一個程式中可以存在一個或者多個執行緒。  兩者的區別在以下兩個方面:
    • 同樣作為基本的執行單元,執行緒是比程式更小的執行單位。
    • 每個程式都有一段專用的記憶體區域。一個程式崩潰後,在保護模式下不會對其它程式產生影響,執行緒是程式內部單一的一個順序流。與此相反,執行緒之間沒有單獨的地址空間,一個執行緒死掉就等於整個程式死掉,執行緒共享記憶體單元(包括程式碼和資料),通過共享的記憶體單元來實現資料交換、實時通訊與不必要的同步操作。  
     
  2. 多執行緒同步程式碼塊      同步是是各執行緒之間協調使用共享資源的以中共方式,如果一個物件(或者變數)同時被多個執行緒訪問,那麼這個物件必須使用執行緒同步。執行緒同步分同步程式碼塊和同步方法兩種。                                                                                                                                                                                                                                           同步程式碼塊格式:
    synchronized(syncObject){
          /**需要同步的程式碼;*/
    }
     同步程式碼塊-例子:
    public class test {
    
    	public static void main(String[] args) {
    		//TextThread為實現Runnable介面的類,該類裡有重寫的run()方法。
    		TextThread t=new TextThread();
    		//開啟了兩個執行緒,
    		new Thread(t).start();
    		new Thread(t).start();
    	}
    
    }
    class TextThread implements Runnable{
    	private int num=3;
    	public void run(){
    		while(true){
    			//由於兩個執行緒訪問的是同一個物件t,因此這個物件要執行緒同步,此處是執行緒同步程式碼塊。
    			synchronized (this){
    				if(num>0){
    					try{
    						Thread.sleep(100);//執行緒休眠
    					}catch(InterruptedException e){
    						System.out.println(Thread.currentThread().getName()+"出錯了!");
    					}
    					System.out.println(Thread.currentThread().getName()+"數字為:"+num--);
    				}else {
    					System.out.println(Thread.currentThread().getName()+"退出了");
    					break;//如果num<0就退出迴圈。
    				}
    			}
    		}
    	}
    }
    上例,Thread-0執行結束後,Thread-1才可以訪問同步程式碼塊。                                                                                                                                                                                        多執行緒同步方法:當一個方法被關鍵字synchrozied宣告後,就只允許一個執行緒來操作這個方法。即一次只能讓一個執行緒執行。                                                                       格式如下:
    訪問控制符 synchonized 返回值型別 方法名稱(引數){
         /**方法體*/
    }
    多執行緒同步方法例子:
    public class ThreadDemo {
    
    	public static void main(String[] args) {
    		ThreadTest1 t=new ThreadTest1();
    		new Thread(t).start();
    		new Thread(t).start();
    		System.out.println(t.call());
    	}
    
    }
    class ThreadTest1 implements Runnable{
    	private int x;
    	private int y;
    	public synchronized void run(){
    		for (int i=0;i<4;i++){
    			x++;
    			y++;
    			try{
    				Thread.sleep(100);
    			}catch(InterruptedException e){
    				System.out.println("The thread is wrong!");
    			}
    			System.out.println(Thread.currentThread().getName()+""+"x="+x+""+"y="+y+""+i);
    		}
    	}
    	public synchronized String call(){
    		String name=Thread.currentThread().getName();
    		return "Hello"+name;
    	}
    }
    執行結果:等應該共6種情況,可以看出每次只執行一個執行緒,且必須等這個執行緒結束才執行下一個執行緒。 
  3. wait()和notify()
  • wait():使執行緒處於等待狀態,並且釋放所持有物件的鎖,要與notify()配套使用。每個java物件都有一個鎖,任何時候該鎖只能由一個執行緒控制。當wait()方法釋放了該物件的鎖時,進入等待池,一直要到執行緒呼叫該物件的notify()和notifyAll()方法,執行緒才可以進入可執行狀態。
  • 喚醒一個等待狀態的執行緒,是由JVM確定喚醒哪個(而非按優先順序),自己並不能確切的喚醒某一個等待狀態的執行緒。
  • notifyAll():喚醒所有處於等待的執行緒,而非給所有喚醒執行緒一個物件的鎖,是讓他們競爭,獲得鎖的執行緒即進入可執行狀態。                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

    

相關文章