Java---11---多線程的兩種建立方式,java---11---多線程
多線程的兩種建立方式:
下面這些東西是API文檔中的:
public class Thread
extends Object
implements Runnable
線程 是程式中的執行線程。Java 虛擬機器允許應用程式並發地運行多個執行線程。
每個線程都有一個優先順序,高優先順序線程的執行優先於低優先順序線程。每個線程都可以或不可以標記為一個精靈。當某個線程中啟動並執行代碼建立一個新 Thread 對象時,該新線程的初始優先順序被設定為建立線程的優先順序,並且若且唯若建立線程是守護線程時,新線程才是精靈。
當 Java 虛擬機器啟動時,通常都會有單個非守護線程(它通常會調用某個指定類的 main 方法)。Java 虛擬機器會繼續執行線程,直到下列任一情況出現時為止:
· 調用了 Runtime 類的 exit 方法,並且安全管理器允許退出操作發生。
· 非守護線程的所有線程都已停止運行,無論是通過從對 run 方法的調用中返回,還是通過拋出一個傳播到 run 方法之外的異常。
建立新執行線程有兩種方法。一種方法是將類聲明為 Thread 的子類。該子類應重寫 Thread 類的 run 方法。接下來可以分配並啟動該子類的執行個體。例如,計算大於某一規定值的質數的線程可以寫成:
class PrimeThread extends Thread{ long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . }}
然後,下列代碼會建立並啟動一個線程:
PrimeThread p = new PrimeThread(143);p.start();
建立線程的另一種方法是聲明實現 Runnable 介面的類。該類然後實現 run 方法。然後可以分配該類的執行個體,在建立 Thread 時作為一個參數來傳遞並啟動。採用這種風格的同一個例子如下所示:
class PrimeRun implements Runnable{ long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . }}
然後,下列代碼會建立並啟動一個線程:
PrimeRun p = new PrimeRun(143);new Thread(p).start();
每個線程都有一個標識名,多個線程可以同名。如果線程建立時沒有指定標識名,就會為其產生一個新名稱。
---------------------------------------------
線程的建立方式:
1.繼承Thread
2.實現Runnable
第一種方式:繼承Thread類
實現步驟:
1.自訂類繼承Thread
2.複習Thread中的run()方法
3.建立該類的對象,調用start()方法,開啟線程並調用run方法
簡單實現:
class MyThread extends Thread{ public void run () { for (int i = 0; i < 100; i++) { System.out.println("MyThread.run()..."+i); } }}public class THREAD{ public static void main (String[] args) { MyThread a = new MyThread(); a.start(); for (int j = 0; j < 100; j++) { System.out.println("THREAD.main()----"+j); } }}
多運行幾次會發現:
i所在的線程和j所在的線程會交替運行
但是每次啟動並執行結果卻是不一樣的
這就是多線程的隨機性
為什麼要覆蓋run方法?
Thread 用於描述線程,該類就定義了一個功能,用於儲存線程要啟動並執行代碼
該儲存功能就是run方法。
第二種建立方式:實現Runnable
Runnable是一個簡單的介面,該介面中只有一個抽象方法:run方法。
實現步驟:
1.定義一個實現Runnable介面的類
2.覆蓋run方法
3.建立該類對象,並以該類對象為參數建立Thread類的對象,從而建立了一個線程
4.調用start方法,開啟線程並調用run方法。
簡單建立:
class MyThread implements Runnable{ public void run () { for (int i = 0; i < 50; i++) { System.out.println("MyThread.run()..."+i); } }}public class THREAD{ public static void main (String[] args) { MyThread a = new MyThread(); Thread a1 = new Thread(a); Thread a2 = new Thread(a); Thread a3 = new Thread(a); Thread a4 = new Thread(a); a1.start(); a2.start(); a3.start(); a4.start(); }}
該例子中建立了四個線程,能夠實現四個線程的交替運行,但是卻看不出是哪個線程執行的,
調用Thread類中的getName方法可以解決這個問題
System.out.println(Thread.currentThread().getName()+"..."+i);
currentThread():擷取當前線程對象
線程的名字
Thread-0
Thread-1
...
線程都有自己預設的名稱,Thread-編號 編號從0開始
也可以自己定義線程的名稱。
class MyThread implements Runnable{ private String name; public MyThread(String name) { this.name = name; } public String GetName() { return name; } public void run () { for (int i = 0; i < 50; i++) { System.out.println(this.GetName()+"..."+i); } }}public class THREAD{ public static void main (String[] args) { MyThread a = new MyThread("My"); MyThread b = new MyThread("Your"); Thread a1 = new Thread(a); Thread a2 = new Thread(b); a1.start(); a2.start(); }}
如果用的是 繼承Thread類的方式 直接用super就可以,
因為Thread類中有getName這個方法,通過建構函式初始化線程,然後直接調用getName方法就行。
class MyThread extends Thread{ private String name; public MyThread(String name) { super(name); }//public String GetName(){//return name;//} public void run () { for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName()+"..."+i); } }}public class THREAD{ public static void main (String[] args) { MyThread a = new MyThread("My"); MyThread b = new MyThread("Your");//Thread a1 = new Thread(a);//Thread a2 = new Thread(b); a.start(); b.start(); }}
兩種方式的區別:
第一種:繼承Thread的方法:
1.缺點:Java語言只允許單繼承,所以該類繼承了Thread之後就不可以再繼承其他的類了
2.優點:編寫簡單。
第二種:實現Runnable介面的方式:
1.缺點:編寫稍顯複雜
2.優點:
a) 避免由於單繼承帶來的局限性
b) 有利於代碼的健壯性,代碼能夠被多個線程共用,代碼與資料是獨立的
代碼存放的位置:
繼承Thread方式:線程代碼存放於Thread子類的run方法中
實現Runnable方式:線程代碼存放於介面子類的run方法中。