Java - 線程控制

你好,未來的Java大師!今天,我們將進入Java線程控制的迷人世界。如果你是編程新手,別擔心——我會一步步引導你,就像這些年來我對無數學生所做的那樣。所以,拿起你的虛擬魔杖(鍵盤),讓我們一起創造編程的魔法吧!

Java - Thread Control

什麼是線程?

在我們跳進控制線程之前,讓我們先了解什麼是線程。想像你在一個廚房裡,正在烹飪一頓複雜的餐點。你是主程序,你所做的每一項任務(切菜、攪拌醬汁、查看烤箱)就像是線程。它們都是同一個整體過程(做晚餐)的一部分,但是它們是可以並發執行的獨立任務。

在Java中,線程是一個輕量級的子進程,是最小的處理單位。它是為程序中的特定任務創建一個獨立執行路径的方式。

為什麼要控制線程?

那麼,我們為什麼想要控制這些線程呢?讓我們繼續使用烹飪的比喻。有時候,你需要暫停攪拌醬汁去查看烤肉。或者你可能需要等待水煮沸才能加入義大利麵。同樣地,在編程中,我們經常需要控制不同線程的流程和時序,以確保我們的程序順暢且高效地運行。

控制Java線程的方法

Java提供了多種方法來控制線程。讓我們來看看這些方法的便捷表格:

方法 描述
start() 開始線程,會調用run()方法
run() 包含構成線程任務的代碼
sleep() 使線程暫停一段指定時間
join() 等待線程終止
yield() 使線程暫時停止,讓其他線程執行
interrupt() 中斷線程,使其停止當前操作
isAlive() 檢查線程是否仍在運行

現在,讓我們深入探討每種方法,並提供一些範例!

1. start() 和 run()

這兩個方法一起工作。以下是一個簡單的範例:

public class MyThread extends Thread {
public void run() {
System.out.println("我的線程正在運行!");
}

public static void main(String args[]) {
MyThread thread = new MyThread();
thread.start();
}
}

在這個範例中,我們創建了一個新的線程並調用它的start()方法。這會依次調用run()方法,其中包含線程將要執行的實際代碼。

2. sleep()

sleep()方法就像在鬧鐘上按下了暫停鍵。它使線程暫停其執行一段指定時間。以下是如何使用它:

public class SleepyThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("線程正在計數:" + i);
try {
Thread.sleep(1000); // 暫停1秒
} catch (InterruptedException e) {
System.out.println("線程被中斷!");
}
}
}

public static void main(String args[]) {
SleepyThread thread = new SleepyThread();
thread.start();
}
}

這個線程會從1數到5,每次計數間隔1秒。就像一個昏昏欲睡的人慢慢數羊!

3. join()

join()方法就像等待你的朋友完成他們的任務後一起去吃午飯。它使當前線程等待直到它所加入的線程完成其執行。以下是一個範例:

public class JoinExample {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("線程 1:" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});

Thread t2 = new Thread(() -> {
try {
t1.join(); // 等待t1完成
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程 2:我等完了!");
});

t1.start();
t2.start();
}
}

在這個範例中,線程2會等待線程1完成後才打印其消息。

4. yield()

yield()方法就像在對話中禮貌地表示——線程可以暫停,讓相同優先級的其他線程運行。然而,這只是給調度器的一個提示,可能會被忽略。以下是一個簡單的範例:

public class YieldExample implements Runnable {
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " 控制中");
Thread.yield();
}
}

public static void main(String[] args) {
Thread t1 = new Thread(new YieldExample(), "線程 1");
Thread t2 = new Thread(new YieldExample(), "線程 2");
t1.start();
t2.start();
}
}

你可能會看到線程輪流控制,但請記住,這不是 guaranteed!

5. interrupt()

interrupt()方法就像輕輕觸碰某人的肩膀以引起他們的注意。它不會立即停止線程,而是設置一個標誌,線程可以檢查。以下是如何使用它:

public class InterruptExample implements Runnable {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("線程正在運行...");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("線程在睡眠中被中斷");
}
System.out.println("線程已經完成。");
}

public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new InterruptExample());
thread.start();
Thread.sleep(5000); // 讓線程運行5秒
thread.interrupt();
}
}

在這個範例中,線程會運行,直到它在5秒後被中斷。

6. isAlive()

isAlive()方法就像檢查某人是否仍在他們的辦公桌前。它返回true如果線程仍在運行。以下是一個快速範例:

public class AliveExample extends Thread {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("線程正在運行:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) throws InterruptedException {
AliveExample thread = new AliveExample();
thread.start();

while (thread.isAlive()) {
System.out.println("主線程將等待直到MyThread仍在運行");
Thread.sleep(1500);
}
System.out.println("主線程運行到完成");
}
}

這個範例顯示主線程在等待並檢查我們的自定義線程是否仍然存活。

總結

好了,各位!我們已經穿越了Java線程控制的世界,探索了每一種方法,就像在新的世界中探险一樣。記住,就像學習烹飪一樣,掌握線程控制需要練習。不要害怕在你的代碼中試驗這些方法。

當我們結束這個課程時,我想到一個學生曾經告訴我,她發現理解線程最終「點醒了」她,當她將它們想像成廚房裡的不同廚師,他們一起工作來烹製一頓飯。所以,找到對你有效比喻!

持續編碼,持續學習,最重要的是,玩得開心!誰知道呢?下一個大型多線程應用程序可能就來自你們其中一位。直到下次見,願你的線程運行順暢,代碼無bug!

Credits: Image by storyset