Thread的常用方法
- public final void setName(String name)
設置當前線程的名字 - public static Thread currentThread()
返回對當前正在執行的線程對象的引用 - public final String getName()
返回當前線程的名字
// 線程方法的介紹
class A extends Thread {
public void run() {
System.out.println("AAAA");
System.out.printf("%s在執行!\n", Thread.currentThread().getName());// Thread-0在執行!
}
}
public class TestThread {
public static void main(String[] args) {
A aa = new A();
aa.start()
System.out.println("BBBB");
System.out.printf("%s在執行!\n", Thread.currentThread().getName()); // main在執行
}
}
線程的控制
- 線程控制的基本方法
方法 | 功能 |
---|---|
isAlive() | 判斷線程是否還“活”着,即線程是否還未終止 |
getPriority | 獲得線程的優先級數值 |
setPriority() | 設置線程的優先級數值 |
Thread.sleep() | 將當前線程睡眠指定毫秒數 |
jion() | 當用某線程的該方法,將當前線程與該線程“合併”,即等待該線程結束,再恢復當前線程的運行 |
yield() | 讓出CPU,當前線程進入就緒隊列等待調度 |
wait() | 當前線程進入對象的wait pool |
notify() / notifyAll() | 喚醒對象的wait pool中的一個 / 所有等待線程 |
線程優先級
線程的優先級用數字來表示,範圍從1到10。
主線程的缺省優先級是5,子線程的優先級默認與其父線程相同。
- Java提供一個線程調度器來監控程序中啓動後進入就緒狀態的所有線程。線程調度器按照線程的優先級決定應調度哪個線程來執行。
- 線程的優先級用數字來表示,範圍從1到10,一個線程的缺省優先級是5.
Thread.MIN_PRIORITY = 1
Thread.MAX_PRIORITY = 10
Thread.NORM_PRIORITY = 5
- 使用下述線程方法獲得或設置線程對象的優先級
int getPriority()
void setPriority(int newPriority)
通常高優先級的線程將先於優先級低的線程執行,但並不總是這樣的,因此實際開發並不單純依賴優先級來決定線程運行次序。
class T1 implements Runnable {
public void run() {
for (int i=0; i<100; ++i)
System.out.println("T1: " + i);
}
}
class T2 implements Runnable {
public void run() {
for (int i=0; i<100; ++i)
System.out.println("------T2: " + i);
}
}
public class TestPriority {
public static void main(String[] args) {
Thread t1 = new Thread(new T1());
Thread t2 = new Thread(new T2());
t1.setPriority(Thread.NORM_PRIORITY + 3);// t1 的優先級被設爲8,比t2優先級5要大,所以線程t1先執行,執行完再執行t2進程
t1.start();
t2.start();
}
}
線程的休眠
- 線程休眠-----暫停執行當前運行中的線程,使之進入阻塞狀態,待經過指定的“延遲時間”後再醒來並轉入到就緒狀態。
- Thread類提供的相關方法:
public static void sleep(long millis)
public static void sleep(long millis, int nanos)
- 由於是靜態方法,可以由Thread直接調用
- sleep()方法會拋出InterruptedException異常,我們必須得對其進行捕捉
class A implements Runnable {
public void run() { // 2行
for (int i=0; i<10; ++i) {
System.out.println(Thread.currentThread().getName() + " " + i);
try {
Thread.sleep(1000); // 這裏的Thread.sleep(1000)會拋出異常
// 所以必須得進行捕捉,不能在2行的後面添加throws Exception
} catch (Exception e) {
}
}
}
}
public class TeatSleep {
public static void main(String[] args) {
A aa = new A();
Thread tt = new Thread(aa);
tt.start();
}
}
無論是繼承Thread類的run方法還是實現了Runnable接口的run方法,都不能拋出任何異常
class A implements Runnable {
public void run() // throws Exception { // 註釋符不能去掉,否則編譯會報錯
}
}
class B extends Thread {
public void run() // throws Exception { // 註釋符不能去掉,否則編譯會報錯
}
}
原因:重寫方法拋出異常的範圍不能大於被重寫方法排除的異常範圍
線程的讓步
- 讓出CPU,給其他線程執行的機會
- 讓運行中的線程主動放棄當前獲得的CPU處理機會,但不是使該線程阻塞,而是使之轉入就緒狀態。
public static void yield()
class MyThread implements Runnable {
public void run() {
for (int i=1; i<=100; ++i) {
System.out.println(Thread.currentThread().getName() + ":" + i);
if (0 == i%10)
Thread.yield();
}
}
}
public class TestYield {
public static void main(String[] args) {
MyThread mt = new MyThread();
Thread t1 = new Thread(mt);
Thread t2 = new Thread(mt);
t1.setName("線程A");
t2.setName("線程B");
t1.start();
t2.start();
}
}
線程的串行化
- 在多線程程序中,如果在一個線程運行的過程中要用到另一個線程的運行結果,則可進行線程的串行化處理
public final void jion() throws InterruptedException
class MyRunner implements Runnable {
public void run() {
for (int i=0; i<50; i++)
System.out.println("子線程:" + i);
}
}
public class TestJoin {
public static void main(String[] args) {
MyRunner r = new MyRunner();
Thread t = new Thread(r);
t.start();
try {
t.jion(); // 7行
} catch(InterruptedException e ) {
e.printStackTrace();
}
for (int i=0; i<50; i++)
System.out.println("主線程:" + i);
}
}
7行的 t.jion()暫停當前正在執行t.jion()的線程,直到t所對應的線程運行終止之後,當前線程纔會獲得繼續執行的機會
注意:t.jion()不是暫停t對象所對應的線程
線程的掛起和恢復
- 線程掛起----暫時停止當前運行中的線程,使之轉入阻塞狀態,並且不會自動恢復運行。
- 線程恢復----- 使得一個已掛起的線程恢復運行。
- Thread類提供的相關方法
public final void suspend()
public final void resume()
- suspend()方法掛起線程時並不釋放其鎖定的資源,這可能會影響其他線程的運行,且容易導致線程的死鎖,已經不提倡使用
生命週期控制
- 如何結束一個線程
class A implements Runnable {
private boolean flag = true;
public void run() {
while (flag)
System.out.println("AAAA");
}
public void shutDown() {
this.flag = false;
}
}
public class TestShutThread {
public static void main(String[] args) {
A aa = new A();
Thread tt = new Thread(aa);
tt.start();
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
aa.shutDown();
}
}