線程狀態(tài)
線程從開啟到結束運行瞭郑,都有它自己的狀態(tài)。Thread類中有一個枚舉類可以表示所有的狀態(tài)鸭你。我們也把它們大致分成這幾個狀態(tài):
- 新建屈张,線程剛new出來的時候
-
就緒,線程調用
start()
后 - 運行袱巨,cpu執(zhí)行線程
-
阻塞阁谆,運行中的線程因為某些操作中斷運行,比如調用
sleep()
方法愉老,阻塞完成后會回到就緒狀態(tài) -
終止场绿,線程的
run()
方法執(zhí)行完畢
Thread的枚舉類State
- NEW,線程剛創(chuàng)建的狀態(tài)
- RUNNABLE俺夕,運行中的線程
- BLOCKED裳凸,線程被阻塞的狀態(tài)
- WAITING,等待執(zhí)行的線程
- TIMED WAITING劝贸,等待sleep結束的線程
- TERMINATED姨谷,執(zhí)行完畢的線程
停止線程
不推薦直接調用線程的 stop()
方法來停止線程。
可以自己寫一個boolean標記來完成線程的停止:
package thread.situation;
public class StopDemo implements Runnable{
private boolean flag=true;
private int i=0;
@Override
public void run()
{
while(flag)
{
System.out.println("子線程執(zhí)行中..."+i++);
}
}
public void stop()
{
flag = false;
}
//主方法
public static void main(String[] args) {
StopDemo s = new StopDemo();
Thread t = new Thread(s);
t.start();
for (int i = 0; i < 100000000 ; i++)
{
System.out.println("Main Thread has execute"+i);
if(i==9000000)
{
s.stop();
System.out.println("Make the subthread stop...");
}
}
}
}
線程的幾種方法:
-
sleep(100)
讓線程阻塞100毫秒映九,阻塞后回到就緒狀態(tài) -
yield()
運行中讓線程回到就緒狀態(tài)梦湘,重新等待 cpu 的調用 -
join()
讓線程插隊執(zhí)行,插隊執(zhí)行的時候其它線程都會進入阻塞狀態(tài),少用捌议。
線程優(yōu)先級
前面已經說過哼拔,調用就緒狀態(tài)的線程是由CPU內部決定的,我們干預不了瓣颅。但有時候倦逐,我們想讓某個線程優(yōu)先執(zhí)行怎么辦呢?我們可以向CPU提建議宫补,也就是設置線程的優(yōu)先級檬姥。
Thread
類中使用[1,10]來表示線程的優(yōu)先級。它還內置了3個優(yōu)先級常量:MIN_PRIORITY
粉怕、NORM_PRIORITY
健民、MAX_PRIORITY
,實際值分別是1贫贝,5秉犹,10。
我們可以在線程 start()
前調用它的 setPriority(int x)
方法設置優(yōu)先級來向CPU建議最好先執(zhí)行哪個線程(當然CPU聽不聽就不知道了)稚晚。
使用 getPriority()
方法可以查看當前線程的優(yōu)先級崇堵。
package thread.situation;
public class StopDemo implements Runnable{
@Override
public void run()
{
System.out.println(Thread.currentThread().getName()+"優(yōu)先級是"+Thread.currentThread().getPriority());
}
}
class Demo{
public static void main(String[] args) throws InterruptedException {
StopDemo s = new StopDemo();
Thread t1 = new Thread(s,"最好的線程");
Thread t2 = new Thread(s,"最差的線程");
Thread t3 = new Thread(s,"有點好的線程");
Thread t4 = new Thread(s,"有點差的線程");
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t3.setPriority(8);
t4.setPriority(3);
t1.start();
t2.start();
t3.start();
t4.start();
System.out.println("主線程的優(yōu)先級是"+Thread.currentThread().getPriority());
}
}
某次輸出結果:
主線程的優(yōu)先級是5
最差的線程優(yōu)先級是1
有點差的線程優(yōu)先級是3
最好的線程優(yōu)先級是10
有點好的線程優(yōu)先級是8
很明顯,CPU不太愿意接受我們的建議客燕。
守護線程
線程其實是有兩種的筑辨。一種是用戶線程,一種是守護線程(Daemon)幸逆。用戶線程就是我們創(chuàng)建出來的線程棍辕,主線程也是用戶線程的一種。守護線程主要是一些服務線程还绘,比如監(jiān)控內存楚昭、垃圾回收線程之類的。它們的區(qū)別在執(zhí)行方式上拍顷。
- 如果是用戶線程抚太,JVM會在所有的用戶線程執(zhí)行完后關機
- 如果是服務線程...我都這么寫了JVM會怎么對待守護線程不用我說了吧(即使有守護線程在運行,JVM還是會裝作看不到然后關機)昔案。
通過調用 Thread
類的 setDeamon()
方法并傳入一個 true
就可以把該類變成守護線程了尿贫。
package thread.situation;
public class StopDemo implements Runnable{
@Override
public void run(){}
}
class Man implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("你"+i+"歲了");
}
System.out.println("http:////// ansl \\\\\\");
}
}
class BigBrother implements Runnable{
@Override
public void run() {
while(true) {
for (int i = 0; i < 20000; i++)
{
System.out.println("Big Brother has watched you"+ i +"times");
}
}
}
}
class Demo{
public static void main(String[] args) throws InterruptedException {
BigBrother bigBrother = new BigBrother();
Man you = new Man();
Thread brotherThread = new Thread(bigBrother);
brotherThread.setDaemon(true);
brotherThread.start();
new Thread(you).start();
}
}
最后一段輸出結果:
你99歲了
Big Brother has watched you54times
////// ansl \\\
Big Brother has watched you55times
Big Brother has watched you56times
Big Brother has watched you57times
Big Brother has watched you58times
Big Brother has watched you59times
Big Brother has watched you60times
Big Brother has watched you61times
Big Brother has watched you62times
Big Brother has watched you63times
Big Brother has watched you64times
Big Brother has watched you65times
Big Brother has watched you66times
Big Brother has watched you67times
Big Brother has watched you68times
Big Brother的循環(huán)還沒跑完,JVM就關機了踏揣。