Java多執行緒的建立和狀態資訊|樂位元組
阿新 • • 發佈:2019-12-31
大家好,我是樂位元組的小樂,好看好學的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()
關於多執行緒的建立和狀態就介紹到這裡,下次我們再說多執行緒的同步和執行緒通訊,請關注樂位元組,原創文章,轉載請註明出處。