黑馬程序員_Java基礎[25]_線程

---------- android培訓 java培訓 、期待與您交流! ----------

【【線程】】
進程:是一個正在執行中的程序。
    每一個進程執行都有一個執行順序,該順序就是一個執行路徑、或者叫一個控制單元
【線程】:就是進程中的一個獨立的控制單元。線程在控制着進程的執行

一個進程中至少有一個線程。(至少一個控制單元)

(在某一個時刻cpu 只能執行一個程序,cpu 在不停的切換。

    一個進程當中,可以有多條路徑。
    線程是進程中的內容,)



java JVM  啓動的時候會有一個進程java.exe
    該進程中至少有一個線程,在負責java程序的執行,
    而且,這個線程運行的代碼存在與main方法中。
    該線程稱之爲主線程

擴展:其實更細節說明jvm,jvm啓動不止一個線程,還有複雜垃圾回收機制的線程


【多線程存在的意義】:

【自定義線程】:

1、通過API的查找,java已經提供了對線程這類事物的描述,就是Thread類
    
創建線程的第一種方式:繼承Thread。
【【步奏】】:
【方法一】:
1、定義類繼承Thread
2、複寫Thread類中的run方法
    複寫的目的是將自定義的代碼存儲在run 方法中,讓線程運行。
3、調用線程的start方法    

發現,運行結果每一次都不同。
因爲多個線程都在獲取cpud 執行權,cpu執行到誰,誰就運行。
明確一點,在某一個時刻,只能有一個程序在運行。(多核除外)

cpu在做着快速的切換,達到看上去同時運行的效果。
我們可以形象的把多線程的運行行爲看作互相搶奪cpu的執行權
    誰搶到誰執行。
這就是多線程的一個特性:隨機性,誰搶到誰執行,至於執行多長,cpu說了算。

爲什麼要覆蓋run(); 方法
Thread 類用於描述線程。
    該類就定義了一個存儲線程要運行的代碼,該存儲功能就是run方法
    也就是說Thread類中的run 方法用於存貯線程要運行的代碼
【【步奏】】:
【方法二】:【必須記住】
1、定義類實現Runnable接口
2、覆蓋Runable 接口中 run 方法
3、通過Thread 類建立線程對象。
4、將Runable 接口中 子類對象作爲事件參數傳遞
--------------------------------------------------------------------------------
例子:
//方法一
class Demo extends Thread{
    public void run(){
        for(int i=0;i<60;i++){
            System.out.println("run"+i);
        }
    }
}

class ThreadDemo{
    public lstatic void main(String []args){
    Demo d=new Demo();//這樣創建對象的同時就創建了線程
    d.start();//開啓並執行線程
    //d.run;//僅僅是對象調用方法,而線程創建了並沒有運行
    /*
    Demo 繼承Thread類 並重載run方法後,在main發放中創建一個對象也就創建好一個線程了。
    想要調用就得使用到start方法。

    */
    for(int i=0;i<60;i++){
            System.out.println("main"+i);
        }
    }
}

--------------------------------------------------------------------------------------
/*自定義多線程的【第二種方式】
 *
 * 需求:簡單的賣票窗口程序
 *       多個窗口同時賣票。
 *   
 * 方式二:實現Runnable 接口
 * 步奏:
 * 1、定義類實現Runnable 接口
 * 2、覆蓋Runnable接口中的run 方法
 *         將線程要運行的代碼存放在該run方法中
 * 3、通過Thread 類建立線程對象
 * 4、將Runnable 接口的子類對象作爲實際參數傳遞給Thread 類的構造函數
 *         爲什麼要將Runnable接口的子類對象傳遞給Thread的構造函數,
 *         因爲,自定義的run方法所屬的對象是Runnable接口的子類對象。
 *         所以要讓線程去指定對對象的run方法
 * 5、調用Thread 類的start方法開啓線程並調用Runnable 接口子類的run方法。
 *
 * 實現方式繼承方式有什麼【區別】呢
 * 實現方式好處:避免了單繼承的侷限性
 * 在定義線程時:建議使用實現方式。
 *
 * 兩種方式的區別:
 * 繼承Thread:線程代碼存放在Thread 子類run方法中
 * 實現Runnable,線程代碼存放在接口的子類run方法中。
 */
//class Ticket extends Thread{//方式一
    //private static int tick=100;//不推薦使用static 因爲他的生命週期太長
class Ticket implements Runnable{//方式二
    private int tick=100;
    public void run(){
        while(true){
            if(tick>0)
                System.out.println(Thread.currentThread().getName()+"買票"+(tick--));
        }
        
    }
}





public class D_Th_test2 {

    public static void main(String[] args) {
        /* 方式一
        Ticket t=new Ticket();
        Ticket t2=new Ticket();
        Ticket t3=new Ticket();
        t.start();
        t2.start();
        t3.start();

         */
        //方式二
        Ticket t=new Ticket();//這只是創建對象
        
        Thread t1=new Thread(t);
        Thread t2=new Thread(t);
        Thread t3=new Thread(t);
        t1.start();
        t2.start();
        t3.start();

        /*把Runnable 子類對象當作參數傳遞給Thread方法的構造函數,
         * 通過調用Thread類的start方法開啓線程並調用Runnable中的run方法

         */
        
    }

}
----------------------------------------------------------------
/*//方式二
 * Test4   學習【同步】以後再回來看該代碼
 */
class Ticket2 implements Runnable{
    private int tick=100;
    
    public void run(){    //run是不能直接改爲同步函數的,因爲while不需要同步,上鎖後會出現一直循環打印的結果,那麼
        while(true){
            //if(tick>0)
            //    System.out.println(Thread.currentThread().getName()+"買票"+(tick--));
            show();//設置同步函數後
        }
        
    }
    
    public synchronized void show(){// 把該函數改爲同步函數即可
        //複製代碼到此後,註釋掉run中代碼
        if(tick>0)
            System.out.println(Thread.currentThread().getName()+"買票"+(tick--));
    }
}






---------- android培訓、 java培訓 、期待與您交流!----------
黑馬官網: http://edu.csdn.net/heima
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章