1. 程式人生 > 程式設計 >Java多執行緒的建立和狀態資訊|樂位元組

Java多執行緒的建立和狀態資訊|樂位元組

大家好,我是樂位元組的小樂,好看好學的Java乾貨又來了!上一篇我們說到了Java多執行緒的概念以及優缺點|樂位元組,本文將接著說Java多執行緒的建立,以及多執行緒的狀態。

一、建立執行緒

1、建立 Thread 的子類

建立: 繼承 Thread +重寫 run

啟動: 建立子類物件 物件.start()

建立 Thread 子類的一個例項並重寫 run 方法,run 方法會在呼叫 start()方法之後被執行,示例如下:

public class MyThread extends Thread { 
public void run(){ 
for(int i=0;i<10;i++){ 
try { 
Thread.sleep(20); //模擬延時
} catch (InterruptedException e) { 
e.printStackTrace(); 
} 
System.out.println("一邊學習多執行緒"
); } } public static void main(String[] args) { //建立子類物件 MyThread myThread = new MyThread(); //啟動執行緒 myThread.start(); //也可以建立匿名子類 Thread thread = new Thread(){ public void run(){ for(int i=0;i<10;i++){ try { Thread.sleep(20);//模擬延時 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("一邊玩QQ"
); } } }; thread.start(); for(int i=0;i<10;i++){ try { Thread.sleep(20); //模擬延時 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("一邊玩微信..."); } } }複製程式碼

2、實現 Runnable 介面(推薦)

面向介面程式設計,避免單繼承侷限

建立: 實現 Runnable +重寫 run

啟動:靜態代理 Thread

a)、建立真實角色 實現類物件
b)、建立代理角色 Thread 物件+真實角色的引用
c)、代理角色.start()

此方式是新建一個實現了 java.lang.Runnable 介面的類的例項,例項中的方法可以被

執行緒呼叫。

缺點: 根據重寫規則,run 方法不能對外宣告異常,不能有返回值

public class MyRunnable implements Runnable { 
public void run(){ 
for(int i=0;i<10;i++){ 
try { 
Thread.sleep(20); //模擬延時 
} catch (InterruptedException e) { 
e.printStackTrace(); 
} 
System.out.println("一邊學習多執行緒"); 
} 
} 
public static void main(String[] args) { 
//使用代理建立執行緒 
Thread thread = new Thread(new MyRunnable()); 
//啟動執行緒 
thread.start(); 
//也可以建立一個實現了Runnable介面的匿名類 
Runnable myRunnable = new Runnable(){ 
public void run(){ 
for(int i=0;i<10;i++){ 
try { 
Thread.sleep(20);//模擬延時 
} catch (InterruptedException e) { 
e.printStackTrace(); 
} 
System.out.println("一邊玩QQ"); 
 
} 
} 
}; 
Thread t = new Thread(myRunnable); 
t.start(); 
for(int i=0;i<10;i++){ 
try { 
Thread.sleep(20); //模擬延時 
} catch (InterruptedException e) { 
e.printStackTrace(); 
} 
System.out.println("一邊玩微信..."); 
} 
} 
} 複製程式碼


優點: 能宣告異常,能有返回值 缺點: 編寫複雜麻煩

public class Call { 
public static void main(String[] args) throws InterruptedException,ExecutionException { 
//建立執行緒 
ExecutorService ser=Executors.newFixedThreadPool(2); 
Race tortoise = new Race("老不死",1000); 
Race rabbit = new Race("小兔子",500); 
//獲取值 
Future<Integer> result1 =ser.submit(tortoise) ; 
Future<Integer> result2 =ser.submit(rabbit) ; 
Thread.sleep(2000); //2秒 
tortoise.setFlag(false); //停止執行緒體迴圈 
rabbit.setFlag(false); 
int num1 =result1.get(); 
int num2 =result2.get(); 
System.out.println("烏龜跑了-->"+num1+"步"); 
System.out.println("小兔子跑了-->"+num2+"步"); 
//停止服務 
ser.shutdownNow(); 
} 
} 
class Race implements Callable<Integer>{ 
private String name ; //名稱 
private long time; //延時時間 
private boolean flag =true; 
private int step =0; //步 
public Race() { 
} 
public Race(String name) { 
super(); 
this.name = name; 
} 
public Race(String name,long time) { 
super(); 
this.name = name; 
this.time =time; 
} 
@Override 
public Integer call() throws Exception { 
while(flag){ 
Thread.sleep(time); //延時 
step++; 
} 
return step; 
} 
public String getName() { 
return name; 
} 
public void setName(String name) { 
this.name = name; 
} 
public long getTime() { 
return time; 
} 
public void setTime(long time) { 
this.time = time; 
} 
public boolean isFlag() { 
return flag; 
} 
public void setFlag(boolean flag) { 
this.flag = flag; 
} 
public int getStep() { 
return step; 
} 
public void setStep(int step) { 
this.step = step; 
} 
} 複製程式碼


二、執行緒的狀態及資訊

1、五種狀態

1)、新生狀態: new
2)、就緒狀態: runnable
3)、執行狀態: running
4)、阻塞狀態: blocked
5)、執行完畢: dead

類似於運動員賽跑,

1)、新生狀態:選出運動員
2)、就緒狀態:走到起跑線,做好跑的動作,槍響後,不是馬上就跑,得有反應時間。
3)、執行狀態:反應完成後,開始跑
4)、阻塞狀態:路邊一個石頭絆倒了,馬上跑起來,嘟囔幾句,踢踢石頭, 不是馬上跑,重新反應進入就 緒。
5)、終止狀態:跑完了,結束了,慢慢的走幾步停下來。


2、阻塞: sleep

模擬網路延時,每個物件 都有一把排他鎖,不會釋放鎖

class Web12306 implements Runnable { 
private int tickets =20; //假設20張票 
private boolean flag =true; 
@Override 
public void run() { 
while(flag){ 
if(tickets>=0){ 
try { 
//模擬延時 
Thread.sleep(200); 
} catch (InterruptedException e) { 
e.printStackTrace(); 
} 
System.out.println(Thread.currentThread().getName()+"-->搶票"+tickets--); 
}else{ 
flag =false; 
} 
} 
} 
public static void main(String[] args) { 
//真實角色 目標 
Runnable target =new Web12306(); 
//代理角色 Thread +真實角色的引用 
Thread proxy1 =new Thread(target,"黃牛A"); 
Thread proxy2 =new Thread(target,"路人甲"); 
//代理行為 
proxy1.start(); //啟動執行緒 
proxy2.start(); //執行緒不安全,資料有問題 
} 
}複製程式碼


3、終止

不要呼叫 stop destory 方法,太暴力,一盆冷水讓其停止。

a、正常執行完畢,迴圈 次數已經到達

b、外部干涉

1)、執行緒中加入標識 -->屬性
2)、執行緒體中 使用改標識 -->死迴圈
3)、對外提供改變改標識的方法 setXxx() terminate() a()...
4)、外部根據適當的時機呼叫該方法


4、當前執行緒

Thread.currentThread()

5、優先順序

只代表概率,不代表絕對先後順序

MIN_PRIORITY : 1

NORM_PRIORITY :5 預設優先順序

MAX_PRIORITY :10

getPriority() setPriority()


關於多執行緒的建立和狀態就介紹到這裡,下次我們再說多執行緒的同步和執行緒通訊,請關注樂位元組,原創文章,轉載請註明出處。