Java多線程的基本概念及意義

一、線程依賴於進程而存在。
           進程,正在運行的程序。是系統進行資源分配和調用的獨立單位。每一個進程都有它自己的內存空間和系統資源。

二、多進程的意義:
       單進程的計算機只能做一件事,而現在都可以做多件事情,支持多進程,可以在一個時間段內執行多個任務。 提高CPU的使用率~

        問題:
                    一邊玩遊戲,一邊聽音樂是同時進行嗎?
                    不是。因爲單COU在某一個時間點上只能做一件事情。(多核可以實現,但是會有很多進程,就不行了)
                    而我們在玩遊戲,或者聽音樂的時候,是CPU在做着程序間的高效切換讓我們覺得是同時進行的。    切換時間超短。

三、線程:
          1.在同一個進程內又可以執行多個任務,而每一個任務我們就可以看成是一個線程。
          2.是程序的執行單元,執行路徑。是程序使用CPU的最基本的單位。
                  a.如果程序只有一條執行路徑,那麼該程序就是單線程程序
                  b.如果程序有多條執行路徑,那麼該程序就是多線程程序
四、多線程的意義:
           1.多線程的存在,不是提高程序的執行速度。其實是爲了提高應用程序的使用率。
            2.程序的執行其實都是在搶CPU的資源,CPU的執行權。
            3.多個進程是在搶這個資源,而其中的某一個進程如果執行路徑比較多,就會有更高的機率搶到CPU的執行權。
            4.我們是不敢保證哪一個線程能夠在哪個時刻搶到,所以線程的執行有隨機性。

五、並行和併發:
        A:並行是邏輯上同時發生,指在某一個時間內同時運行多個程序
        B:併發是物理上同時發生,指在某一個時間點同時運行多個程序

六、Java運行原理
        java命令會啓動java虛擬機,啓動JVM,等於啓動了一個應用程序,也就是啓動了一個進程。該進程會自動啓動一個“主線程”,然後主線程去調用某個類的main方法。所以main方法運行在主線程中。在此之前的所有程序都是單線程。
        jvm虛擬機至少啓動了垃圾回收線程和主線程(調用main方法),所以是多線程的
                垃圾回收是以防出現內存溢出

C/C++可以去調用系統功能並創建進程,然後由Java去調用,實現多線程程序(Java不可以直接調用系統功能)

七、繼承Thread(線程)類
        a.自定義類繼承Thread類。
        b.在自定義類中重寫run()方法(run()方法執行需要被線程執行的代碼)。
        c.創建對象。
        d.啓動線程。

public class MyThread  extends Thread{
        //比較耗時的程序才執行線程
        public void run() {
                 //添加需要被線程的代碼
        }
}    
public class MyThreadDemo {
        public static void main(String[] args) {
                MyThread my = new MyThread();
                  //my.run(); 直接調用無線程效果
                  //若直接調用run()方法就相當於普通方法的調用 
                  //因此還有另一個方法start();        
                  //run()僅僅是封裝被線程執行的代碼,直接調用是普通方法
                  //start()首先啓動了線程,然後由jvm調用線程的run()方法
                  my.start();
                  //my.start();再此調用,相當於my線程被調用了兩次,出現IllegalThreadStateException:非法的線程狀態
                
                  //若想兩個線程啓動,需創建兩個對象。
 		  MyThread my1 = new MyThread();
                  MyThread my2 = new MyThread();
 
                  my1.start();
                  my2.start();
        }
} 

public final String  getName();  //該方法可以獲取線程的名稱,在自定義類中的 run方法中使用   默認顯示Thread-0,Thread-1...
八、自定義線程的名稱兩種方法:
            a.public final String  setName();  //該方法可以自定義線程的名稱,在主類中調用my1.setName("***");   
            b.通過在自定義類中加入帶參構造方法如public MyThread(String name) {super(name);} ,然後創建對象時直接加入名稱如MyThread my1 = new MyThread(“第一個線程”);   

九、線程調度(兩種)以及設置線程優先級:
            1.分時調度模型。所有線程輪流使用CPU的使用權,平均分配每個線程佔用CPU的時間片
            2.搶佔式調度模型。優先讓優先級高的線程使用CPU,若相同,則隨機選擇,優先級高的線程獲取CPU的時間片相對多一些。
Java使用的是搶佔式調度模型。
設置線程優先級:
            public final int getPriority();  //返回線程對象的優先級。默認優先級是5。
            public final void setPriority(); //設置線程的優先級。  
            MAX_PRIORITY最大優先級值是10
            MIN_PRIORITY最小優先級是1
            NORM_PRIORITY默認優先級是5
線程優先級別高僅僅表示線程獲取的CPU時間片的機率高,但是要在多次運行的時候才能看到比較好的效果。

十、線程控制:
            父類(Thread)方法:
           a.線程休眠
                     public static void sleep(long millis); 
                     //指定毫秒內休眠    
                     //自定義類中run()裏調用 Thread.sleep(millis);
           b.線程加入   
                     public final void join();  
                     //等待該線程終止,其他線程再開始  
                     //主類中調用
           c.線程禮讓
                     public static void yield(); 
                     //暫停當前正在執行的線程對象,並執行其他線程
                     //自定義類中調用
                     //讓多個線程的執行更和諧,但不能保證一個線程一次。
           d.後臺線程
                     public final void setDaemon(boolean on);
                     //將該線程標記爲守護線程或用戶線程,當正在運行的線程都是守護線程時(即主線程滅亡,守護線程隨之消失),Java虛擬機退出
                    //該方法必須在啓動線程前調用
                    //主類中調用
           e.中斷線程
                     public final void stop();
                     //該方法已過時,但還可以使用。不建議使用,顯示stop();
                     //多長時間線程沒有進行就結束了
                     //主類中調用
                     public void interrupt();
                     //把線程的狀態終止,拋出異常InterruptedException

十一、線程的生命週期
  1. 新建:創建線程對象
  2. 就緒:有執行資格,沒有執行權
  3. 運行:有執行資格,有執行權權  
    •   阻塞:由於一些操作讓線程處於該狀態。沒有執行資格,沒有執行權,而另一些操作卻可以把它激活,激活後處於就緒狀態
  4. 死亡:線程對象變成垃圾,等待回收

新建→(start())→就緒→(獲取到了CPU的執行權)→運行→(run()結束、中斷線程)→死亡(等待被回收)
運行時也許會有阻塞sleep(),wait(),時間(sleep())到後或喚醒(notify())後繞到就緒狀態,再運行
被別的線程搶到執行權就回到就緒狀態

十二、實現多線程的方式:
方式一:繼承Thread類
              a.自定義類繼承Thread類
              b.在自定義類中重寫run()方法
              c.創建自定義類的對象
              d.啓動線程的對象
方式二:實現Runnable接口(大多數使用)
              a.自定義類實現Runnable接口
              b.在自定義類中重寫run()方法
              c.創建自定義類的對象
              d.創建Thread類的對象,並把c步驟創建的對象作爲構造參數傳遞
              優點:避免由於單繼承帶來的侷限性
                        適合多個程序的代碼處理同一個資源的情況,把線程同程序的代碼、數據有效分離,較好的體現了面向對象的設計思想。

 

多線程是java學習進階的重要知識,循序漸進的學習會收穫很多

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章