線程---Day22

併發與並行java

  併發:指兩個或多個事件在同一個時間段內發生。 編程

  並行:指兩個或多個事件在同一時刻發生(同時發生)多線程

  在操做系統中,安裝了多個程序,併發指的是在一段時間內宏觀上有多個程序同時運行,這在單CPU系統中,每一時刻只能有一道程序執行,即微觀上這些程序是分時的交替運行,只不過是給人的感受是同時運行,那是由於分時交替運行的時間是很是短的、而在多個CPU系統中,則這些能夠併發執行的程序即可以分配到多個處理器上(CPU),實現多任務並行執行, 即利用每一個處理器來處理一個能夠併發執行的程序,這樣多個程序即可以同時執行。目前電腦市場上說的多核 CPU,即是多核處理器,核越多,並行處理的程序越多,能大大的提升電腦運行的效率。 併發

線程調度編輯器

  單核處理器的計算機確定是不能並行的處理多個任務的,只能是多個任務在單個CPU上併發運行。同理,線程也是同樣的,從宏觀角度上理解線程是並行運行的,可是從微觀角度上分析倒是串行運行的,即一個線程一個線程的去運行,當系統只有一個CPU時,線程會以某種順序執行多個線程,咱們把這種狀況稱之爲線程調度。 ide

  分類:spa

    分時調度:全部線程輪流使用 CPU 的使用權,平均分配每一個線程佔用CPU的時間。 操作系統

    搶佔式調度:優先讓優先級高的線程使用 CPU,若是線程的優先級相同,那麼會隨機選擇一個(線程隨機性),Java使用的爲搶佔式調度線程

      搶佔式調度詳解code

        大部分操做系統都支持多進程併發運行,如今的操做系統幾乎都支持同時運行多個程序。好比:如今我 們上課一邊使用編輯器,一邊使用錄屏軟件,同時還開着畫圖板,dos窗口等軟件。此時,這些程序是 在同時運行,」感受這些軟件好像在同一時刻運行着「。 實際上,CPU(中央處理器)使用搶佔式調度模式在多個線程間進行着高速的切換。對於CPU的一個核而 言,某個時刻,只能執行一個線程,而 CPU的在多個線程間切換速度相對咱們的感受要快,看上去就是 在同一時刻運行。 其實,多線程程序並不能提升程序的運行速度,但可以提升程序運行效率,讓CPU的 使用率更高。

線程與進程 

  進程:是指一個內存中運行的應用程序,每一個進程都有一個獨立的內存空間,一個應用程序能夠同時運行多個進程;進程也是程序的一次執行過程,是系統運行程序的基本單位;系統運行一個程序便是一個進程從建立、運行到消亡的過程。

  線程:線程是進程中的一個執行單元,負責當前進程中程序的執行,一個進程中至少有一個線程。一個進程中是能夠有多個線程的,這個應用程序也能夠稱之爲多線程程序。 

  總之:一個程序運行後至少有一個進程,一個進程中能夠包含多個線程

建立線程類 

  Java使用 java.lang.Thread 類表明線程,全部的線程對象都必須是Thread類或其子類的實例。每一個線程的做用是 完成必定的任務,實際上就是執行一段程序流即一段順序執行的代碼。Java使用線程執行體來表明這段程序流。 Java中經過繼承Thread類來建立並啓動多線程的步驟以下: 

  1. 定義Thread類的子類,並重寫該類的run()方法,該run()方法的方法體就表明了線程須要完成的任務,所以把 run()方法稱爲線程執行體。

  2. 建立Thread子類的實例,即建立了線程對象

  3. 調用線程對象的start()方法來啓動該線程

 1 package demosummary.thread;  2 
 3 public class MyThread extends Thread {  4     //定義線程名稱的構造方法
 5     public MyThread(String name) {  6         super(name);  7  }  8     //重寫run方法
 9  @Override 10     public void run() { 11         for (int i = 0; i < 5; i++) { 12             System.out.println(getName() + ":正在執行第" + i + "線程"); 13  } 14  } 15 
16     public static void main(String[] args) { 17         //建立線程對象
18         MyThread myThread = new MyThread("新的線程"); 19         //開啓線程
20  myThread.start(); 21         //執行for循環
22         for (int i = 0; i < 5; i++) { 23             System.out.println("正在執行主線程:"+i); 24  } 25  } 26 }

多線程原理 

 1 package demosummary.thread;  2 
 3 public class MyThread extends Thread {  4     //定義線程名稱的構造方法
 5     public MyThread(String name) {  6         super(name);  7  }  8     //重寫run方法
 9  @Override 10     public void run() { 11         for (int i = 0; i < 5; i++) { 12             System.out.println(getName() + ":正在執行第" + i + "線程"); 13  } 14  } 15 
16     public static void main(String[] args) { 17         System.out.println("這裏是main線程"); 18         //建立線程對象
19         MyThread myThread = new MyThread("小強"); 20         //開啓線程
21  myThread.start(); 22         //執行for循環
23         for (int i = 0; i < 5; i++) { 24             System.out.println("旺財:"+i); 25  } 26  } 27 }

  

  程序啓動運行main時候,java虛擬機啓動一個進程,主線程main在main()調用時候被建立。隨着調用mt的對象的 start方法,另一個新的線程也啓動了,這樣,整個應用就在多線程下運行,多線程執行時,在棧內存中,其實每個執行線程都有一片本身所屬的棧內存空間。進行方法的壓棧和彈棧

  

Thread類

  構造方法

    public Thread() :分配一個新的線程對象。

    public Thread(String name) :分配一個指定名字的新的線程對象。

    public Thread(Runnable target) :分配一個帶有指定目標新的線程對象。

    public Thread(Runnable target,String name) :分配一個帶有指定目標新的線程對象並指定名字。

  經常使用方法

    public String getName() :獲取當前線程名稱。

    public void start() :致使此線程開始執行; Java虛擬機調用此線程的run方法。

    public void run() :此線程要執行的任務在此處定義代碼。

    public static void sleep(long millis) :使當前正在執行的線程以指定的毫秒數暫停(暫時中止執行)。

    public static Thread currentThread() :返回對當前正在執行的線程對象的引用。 

  建立線程方式有兩種,一種是繼承Thread類方式,一種是實現Runnable接口方式

建立線程(實現Runnable接口)

  採用 java.lang.Runnable 也是很是常見的一種,咱們只須要重寫run方法便可

  方法:

    1. 定義Runnable接口的實現類,並重寫該接口的run()方法,該run()方法的方法體一樣是該線程的線程執行體。

    2. 建立Runnable實現類的實例,並以此實例做爲Thread的target來建立Thread對象,該Thread對象纔是真正 的線程對象。

    3. 調用線程對象的start()方法來啓動線程。

 1 package demosummary.thread;  2 
 3 public class MyRunnable implements Runnable {  4     //重寫run方法
 5  @Override  6     public void run() {  7         for (int i = 0; i < 5; i++) {  8             System.out.println(Thread.currentThread().getName() + "---" + i);  9  } 10  } 11 
12     public static void main(String[] args) { 13         //建立類任務對象
14         MyRunnable myRunnable = new MyRunnable(); 15         //建立線程
16         Thread thread = new Thread(myRunnable, "德瑪"); 17         //開啓線程
18  thread.start(); 19         for (int i = 0; i < 5; i++) { 20             System.out.println("皇子" + "---" + i); 21  } 22  } 23 }

  經過實現Runnable接口,使得該類有了多線程類的特徵。run()方法是多線程程序的一個執行目標。全部的多線程 代碼都在run方法裏面。Thread類實際上也是實現了Runnable接口的類。 在啓動的多線程的時候,須要先經過Thread類的構造方法Thread(Runnable target) 構造出對象,而後調用Thread 對象的start()方法來運行多線程代碼。
實際上全部的多線程代碼都是經過運行Thread的start()方法來運行的。所以,不論是繼承Thread類仍是實現 Runnable接口來實現多線程,最終仍是經過Thread的對象的API來控制線程的,熟悉Thread類的API是進行多線程 編程的基礎

  注意:Runnable對象僅僅做爲Thread對象的target,Runnable實現類裏包含的run()方法僅做爲線程執行體。 而實際的線程對象依然是Thread實例,只是該Thread線程負責執行其target的run()方法

Thread和Runnable的區別

  實現Runnable接口比繼承Thread類所具備的優點:

    1. 適合多個相同的程序代碼的線程去共享同一個資源。

    2. 能夠避免java中的單繼承的侷限性。

    3. 增長程序的健壯性,實現解耦操做,代碼能夠被多個線程共享,代碼和線程獨立。

    4. 線程池只能放入實現Runable或Callable類線程,不能直接放入繼承Thread的類。

  注意:在java中,每次程序運行至少啓動2個線程。一個是main線程,一個是垃圾收集線程。由於每當使用 java命令執行一個類的時候,實際上都會啓動一個JVM,每個JVM其實在就是在操做系統中啓動了一個進程

匿名內部類方式實現線程的建立

  使用線程的內匿名內部類方式,能夠方便的實現每一個線程執行不一樣的線程任務操做

 1 package demosummary.thread;  2 
 3 public class InnerClassThread {  4     public static void main(String[] args) {  5         MyRunnable myRunnable = new MyRunnable(){  6           public void run(){  7               for (int i = 1; i <= 5; i++) {  8                   System.out.println("德瑪---"+i);  9  } 10  } 11  }; 12         new Thread(myRunnable).start(); 13  } 14 }
相關文章
相關標籤/搜索