最近在Review線程專欄,修改了諸多之前描述不夠嚴謹的地方,凡是帶有Review標記的文章都是修改過了。本篇文章是插進來的,因爲原來沒有寫,現在來看傳統線程描述的不太完整,所以就補上了。理解了線程同步和線程通信之後,再來看本文的知識點就會簡單的多了,本文是做爲傳統線程知識點的一個補充。有人會問:JDK5之後有了更完善的處理多線程問題的類(併發包),我們還需要去了解傳統線程嗎?答:需要。在實際開發中,無外乎兩種情況,一個是開發新內容,另一個是維護原有程序。開發新內容可以使用新的技術手段,但是我們不能保證原有程序是用什麼實現的,所以我們需要了解原有的。另外一點,瞭解傳統線程的工作原理,使我們在使用併發包時更加得心應手。
線程中斷
void |
interrupt() 中斷線程。 |
static boolean |
interrupted() 測試當前線程是否已經中斷。 |
boolean |
isInterrupted() 測試線程是否已經中斷。 |
- public class InterruptTest {
- public static void main(String[] args) throws InterruptedException {
- MyThread t = new MyThread("MyThread");
- t.start();
- Thread.sleep(100);// 睡眠100毫秒
- t.interrupt();// 中斷t線程
- }
- }
- class MyThread extends Thread {
- int i = 0;
- public MyThread(String name) {
- super(name);
- }
- public void run() {
- while(true) {// 死循環,等待被中斷
- System.out.println(getName() + getId() + "執行了" + ++i + "次");
- }
- }
- }
- public class InterruptTest {
- public static void main(String[] args) throws InterruptedException {
- MyThread t = new MyThread("MyThread");
- t.start();
- Thread.sleep(100);// 睡眠100毫秒
- t.interrupt();// 中斷t線程
- }
- }
- class MyThread extends Thread {
- int i = 0;
- public MyThread(String name) {
- super(name);
- }
- public void run() {
- while(!isInterrupted()) {// 當前線程沒有被中斷,則執行
- System.out.println(getName() + getId() + "執行了" + ++i + "次");
- }
- }
- }
這樣的話,線程被順利的中斷執行了。很多人實現一個線程類時,都會再加一個flag標記,以便控制線程停止執行,其實完全沒必要,通過線程自身的中斷狀態,就可以完美實現該功能。如果線程在調用 Object 類的 wait()、wait(long) 或 wait(long, int) 方法,或者該類的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法過程中受阻,則其中斷狀態將被清除,它還將收到一個 InterruptedException。 我們可以捕獲該異常,並且做一些處理。另外,Thread.interrupted()方法是一個靜態方法,它是判斷當前線程的中斷狀態,需要注意的是,線程的中斷狀態會由該方法清除。換句話說,如果連續兩次調用該方法,則第二次調用將返回 false(在第一次調用已清除了其中斷狀態之後,且第二次調用檢驗完中斷狀態前,當前線程再次中斷的情況除外)。
線程讓步
static void |
yield() 暫停當前正在執行的線程對象,並執行其他線程 |
- public class YieldTest {
- public static void main(String[] args) throws InterruptedException {
- // 創建線程對象
- YieldThread t1 = new YieldThread("t1");
- YieldThread t2 = new YieldThread("t2");
- // 啓動線程
- t1.start();
- t2.start();
- // 主線程休眠100毫秒
- Thread.sleep(100);
- // 終止線程
- t1.interrupt();
- t2.interrupt();
- }
- }
- class YieldThread extends Thread {
- int i = 0;
- public YieldThread(String name) {
- super(name);
- }
- public void run() {
- while(!isInterrupted()) {
- System.out.println(getName() + "執行了" + ++i + "次");
- if(i % 10 == 0) {// 當i能對10整除時,則讓步
- Thread.yield();
- }
- }
- }
- }
輸出結果略,從輸出結果可以看到,當某個線程(t1或者t2)執行到10次、20次、30次等時,就會馬上切換到另一個線程執行,接下來再交替執行,如此往復。注意,如果存在synchronized線程同步的話,線程讓步不會釋放鎖(監視器對象)。
線程睡眠
static void |
sleep(long millis) 在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行)。 |
static void |
sleep(long millis, int nanos) 在指定的毫秒數加指定的納秒數內讓當前正在執行的線程休眠(暫停執行)。 |
- public class SleepTest {
- public static void main(String[] args) {
- // 創建共享對象
- Service service = new Service();
- // 創建線程
- SleepThread t1 = new SleepThread("t1", service);
- SleepThread t2 = new SleepThread("t2", service);
- // 啓動線程
- t1.start();
- t2.start();
- }
- }
- class SleepThread extends Thread {
- private Service service;
- public SleepThread(String name, Service service) {
- super(name);
- this.service = service;
- }
- public void run() {
- service.calc();
- }
- }
- class Service {
- public synchronized void calc() {
- System.out.println(Thread.currentThread().getName() + "準備計算");
- System.out.println(Thread.currentThread().getName() + "感覺累了,開始睡覺");
- try {
- Thread.sleep(10000);// 睡10秒
- } catch (InterruptedException e) {
- return;
- }
- System.out.println(Thread.currentThread().getName() + "睡醒了,開始計算");
- System.out.println(Thread.currentThread().getName() + "計算完成");
- }
- }
- t1準備計算
- t1感覺累了,開始睡覺
- t1睡醒了,開始計算
- t1計算完成
- t2準備計算
- t2感覺累了,開始睡覺
- t2睡醒了,開始計算
- t2計算完成
線程合併
void |
join() 等待該線程終止。 |
void |
join(long millis) 等待該線程終止的時間最長爲 millis 毫秒。 |
void |
join(long millis, int nanos) 等待該線程終止的時間最長爲 millis 毫秒 + nanos 納秒。 |
- public class JoinTest {
- public static void main(String[] args) throws InterruptedException {
- JoinThread t1 = new JoinThread("t1");
- JoinThread t2 = new JoinThread("t2");
- t1.start();
- t2.start();
- t1.join();
- t2.join();
- System.out.println("主線程開始執行!");
- }
- }
- class JoinThread extends Thread {
- public JoinThread(String name) {
- super(name);
- }
- public void run() {
- for(int i = 1; i <= 10; i++)
- System.out.println(getName() + getId() + "執行了" + i + "次");
- }
- }
線程優先級
java.lang.Thread | ||
---|---|---|
public static final int |
MAX_PRIORITY |
10 |
public static final int |
MIN_PRIORITY |
1 |
public static final int |
NORM_PRIORITY |
5 |