Java 控制線程
1、join
public class JoinThreadTest extends Thread {
public JoinThreadTest(String name){
super(name);
}
@Override
public void run() {
for(int i = 0; i < 100; i++){
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) {
for(int i = 0; i < 1000; i++){
if (i== 20) {
JoinThreadTest joinThreadTest = new JoinThreadTest("JoinThread");
joinThreadTest.start();
try {
joinThreadTest.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
當調用join方法後,主線程將進入阻塞狀態,直到被join()方法加入的join線程執行完成為止。通常用來將大問題化為小問題,每個小問題分配一個線程,當這些小問題線程執行完成後,再調用主線程做進一步的處理。
2、後台線程Daemon
主線程默認是前台線程,由前台線程創建的線程默認是前台線程,由後台線程創建的線程默認為後台線程。當所有的前台線程都死亡後,後台線程會自動死亡。設置線程為後台線程,調用setDaemon(true)必須在start()之前調用,判斷一個線程是否為後台線程可用isDaemon()判斷。
public class DaemonThreadTest extends Thread{
public DaemonThreadTest(String name){
super(name);
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) {
DaemonThreadTest daemonThreadTest = new DaemonThreadTest("DaemonThread");
daemonThreadTest.setDaemon(true);
daemonThreadTest.start();
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
運行如上代碼後可知,DaemonThread不會輸出到999,而是當主線成執行完後,過了一段時間後,DaemonThread也就結束了。
3、sleep 和 yield
sleep調用後使線程進入阻塞狀態,在該線程的睡眠時間內,即使cpu空閒,線程也不會獲得執行機會。睡眠結束後,線程進入就緒狀態,等待調度進入運行狀態。對所有優先級的線程有效。
yield 只是簡單讓當前線程暫停一下,使線程調度器重新調度,只對優先級大於等於當前線程的線程有效。當前線程也有可能在暫停一下後,立即調度再次進入運行態。
另外調用sleep會拋出InterruptException,而yield不會。
public class YieldTest extends Thread {
public YieldTest(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + " " + i);
if (i== 20) {
Thread.yield();
}
}
}
public static void main(String[] args) {
YieldTest yieldTest1 = new YieldTest("High");
yieldTest1.setPriority(MAX_PRIORITY);
yieldTest1.start();
YieldTest yieldTest2 = new YieldTest("Low");
yieldTest2.setPriority(MIN_PRIORITY);
yieldTest2.start();
}
}
由於如上代碼設置了不同優先級,執行如上代碼,當執行到i==20時,High線程雖然讓出資源,但是優先級高,重新調度後,還是High線程繼續執行,注釋掉設置優先級的兩行代碼後執行,可發現在i==20後,線程調度,High線程會出讓資源給Low運行。
4、改變線程的優先級
線程優先級設置如上例,子線程的優先級默認與父線程的優先級一致。