線程的優(yōu)先級(jí)
在操作系統(tǒng)中跃惫,線程存在優(yōu)先級(jí)關(guān)系,具有高優(yōu)先級(jí)的線程會(huì)獲得更多CPU的資源宙项,優(yōu)先級(jí)低的線程會(huì)獲得少的CPU資源呢。在Java虛擬機(jī)中株扛,線程的優(yōu)先級(jí)也是如此尤筐。在Java中,線程分為10個(gè)優(yōu)先級(jí)洞就。下面我們先了解一下線程優(yōu)先級(jí)的性質(zhì)盆繁。
- 線程的優(yōu)先級(jí)具有繼承性:即一個(gè)類被繼承之后優(yōu)先級(jí)也會(huì)被繼承。
- 線程的優(yōu)先級(jí)具有規(guī)則性:高優(yōu)先級(jí)的線程總是大部分情況下先執(zhí)行完
- 線程優(yōu)先級(jí)具有不確定性:雖然CPU的資源分配的多了奖磁,但是線程在執(zhí)行的時(shí)候并不是按照一定計(jì)劃執(zhí)行的改基,所以執(zhí)行結(jié)果往往是不確定的。
如何設(shè)置線程的優(yōu)先級(jí)咖为?
Java中使用public final void setPriority(int newPriority)來設(shè)置線程的優(yōu)先級(jí)秕狰。
下面是一段實(shí)例:
public class Main {
public static void main(String[] args){
TestThread test=new TestThread();
test.setPriority(10);
}
public static class TestThread extends Thread{
public void run(){
System.out.println("Hello world");
}
}
}
這段代碼把test實(shí)例的線程設(shè)置為10
寫兩個(gè)線程,設(shè)置優(yōu)先級(jí)躁染,觀察運(yùn)行結(jié)果鸣哀。下面是例子:
public class Main {
public static void main(String[] args){
TestThread test=new TestThread();
TestThread test2=new TestThread();
test.setPriority(10);
test2.setPriority(6);
test.start();
test2.start();
}
public static class TestThread extends Thread{
public void run(){
for(int i=0;i<50;i++){
System.out.println(Thread.currentThread().getId()+":"+i);
}
}
}
}
優(yōu)先級(jí):源碼分析
我們現(xiàn)在來看看JDK在線程上的源代碼
首先是設(shè)置優(yōu)先級(jí)的方法:
public final void setPriority(int newPriority) {
ThreadGroup g;
checkAccess();
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
這也是一個(gè)final方法,不能被覆蓋吞彤,我們發(fā)現(xiàn)我衬,JDK中設(shè)置優(yōu)先級(jí)要有一個(gè)最大值和最小值的叹放,我們來看看這兩個(gè)值:
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
從這里我們可以看出來線程的優(yōu)先級(jí)分為1-10,中間還有一個(gè)值為5.那么5是什么呢挠羔?就是線程優(yōu)先級(jí)的默認(rèn)值井仰,在我們程序中,如果沒有規(guī)定線程的優(yōu)先級(jí)破加,那么線程優(yōu)先級(jí)為5俱恶。
守護(hù)線程
什么是守護(hù)線程呢?用過Linux操作系統(tǒng)的童鞋對(duì)于Linux下的守護(hù)進(jìn)程一定有了解范舀,守護(hù)線程和守護(hù)進(jìn)程的道理基本一致合是。在Java中,存在兩種線程锭环,一種是用戶線程聪全,一種是守護(hù)線程。守護(hù)線程是一種特殊的線程辅辩,他在執(zhí)行的是一種后臺(tái)服務(wù)难礼,當(dāng)一個(gè)系統(tǒng)中不存在非守護(hù)線程的時(shí)候,守護(hù)線程也會(huì)自己銷毀汽久,典型的守護(hù)線程就是JVM的垃圾回收線程鹤竭。
設(shè)置守護(hù)線程很簡(jiǎn)單踊餐,下面是一個(gè)簡(jiǎn)單的例子:
public class Main {
public static void main(String[] args) throws InterruptedException {
TheThread theThread=new TheThread();
theThread.setDaemon(true);//設(shè)置守護(hù)線程
theThread.start();
Thread.sleep(5000);
System.out.println("全都退出啦");
}
public static class TheThread extends Thread{
public void run(){
int i = 0;
while (true){
i++;
System.out.println(Thread.currentThread().getId()+":"+i);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
example: 垃圾回收線程就是一個(gè)經(jīng)典的守護(hù)線程景醇,當(dāng)我們的程序中不再有任何運(yùn)行的Thread,程序就不會(huì)再產(chǎn)生垃圾,垃圾回收器也就無事可做吝岭,所以當(dāng)垃圾回收線程是JVM上僅剩的線程時(shí)三痰,垃圾回收線程會(huì)自動(dòng)離開。它始終在低級(jí)別的狀態(tài)中運(yùn)行窜管,用于實(shí)時(shí)監(jiān)控和管理系統(tǒng)中的可回收資源散劫。
生命周期:守護(hù)進(jìn)程(Daemon)是運(yùn)行在后臺(tái)的一種特殊進(jìn)程。它獨(dú)立于控制終端并且周期性地執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件幕帆。也就是說守護(hù)線程不依賴于終端获搏,但是依賴于系統(tǒng),與系統(tǒng)“同生共死”失乾。那Java的守護(hù)線程是什么樣子的呢常熙。當(dāng)JVM中所有的線程都是守護(hù)線程的時(shí)候,JVM就可以退出了碱茁;如果還有一個(gè)或以上的非守護(hù)線程則JVM不會(huì)退出裸卫。
當(dāng)java虛擬機(jī)中沒有非守護(hù)線程在運(yùn)行的時(shí)候,java虛擬機(jī)會(huì)關(guān)閉纽竣。當(dāng)所有常規(guī)線程運(yùn)行完畢以后墓贿,守護(hù)線程不管運(yùn)行到哪里茧泪,虛擬機(jī)都會(huì)退出運(yùn)行。所以你的守護(hù)線程最好不要寫一些會(huì)影響程序的業(yè)務(wù)邏輯聋袋。否則無法預(yù)料程序到底 會(huì)出現(xiàn)什么問題队伟。