以下是原文翻译成繁體中文的內容,使用Markdown格式:

Java - Creating a Thread

# Java - 創建一個線程

你好,未來的Java大師!今天,我們將要進入Java線程的精彩世界。別擔心你對編程還是新手;我會一步步引導你,就像我過去幾年來對無數學生做的一樣。所以,拿起你喜歡的飲料,舒適地坐好,我們一起開始這場線程冒險吧!

## 什麼是線程?

在我們跳進創建線程之前,讓我們先了解線程到底是什麼。想像你在一個廚房裡,正在烹調一頓美味的晚餐。你同時切蔬菜、攪拌醬汁和查看烤箱。這些任務中的每一個就像是計算機程序中的一個線程——它們是能夠並行運行的獨立任務。

在Java中,線程是程序中最小的執行單位。它允許你的程序的不同部分能夠同時運行,使你的應用程序更加高效和響應。

## 為什麼使用線程?

你可能會想,"我為什麼要麻煩去處理線程呢?" 來,讓我給你講個小故事。多年前,我為一個攝影俱樂部開發一個簡單的圖像處理應用程序。這個應用程序對小圖像來說運行得很好,但當用戶嘗試處理大尺寸、高解析度的照片時,它會卡住。罪魁禍首是什麼呢?一切都是在一個單一線程上運行的!通過實現多線程,我們能夠在背景中處理圖像,同時保持用戶界面的響應。攝影俱樂部的成員非常高興,我也從中學到了關於線程力量的寶貴教訓。

## 在Java中創建線程

在Java中,有兩種主要的方法來創建線程:

1. 實現Runnable接口
2. 繼承Thread類

讓我們通過一些實際的例子來探討這兩種方法!

### 方法1:實現Runnable接口

這種方法通常被認為是創建線程的首選方式,因為它不要求你去繼承Thread類,這樣你的類就可以繼承其他類(如果需要)。

這裡有一個簡單的例子:

```java
public class MyRunnable implements Runnable {
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println("使用Runnable的線程: " + i);
            try {
                Thread.sleep(1000); // 暫停1秒
            } catch (InterruptedException e) {
                System.out.println("線程被中斷。");
            }
        }
    }

    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();

        // 主線程
        for (int i = 1; i <= 5; i++) {
            System.out.println("主線程: " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("主線程被中斷。");
            }
        }
    }
}

讓我們來分解這段代碼:

  1. 我們創建一個名為MyRunnable的類,它實現了Runnable接口。
  2. 我們覆寫了run()方法,這定義了線程啟動時會執行的操作。
  3. main方法中,我們創建了MyRunnable的實例,並將它傳遞給新的Thread對象。
  4. 我們調用線程的start()方法來開始它的執行。
  5. 主線程也打印數字,展示了兩個線程是如何並行運行的。

當你運行這個程序時,你會看到來自兩個線程的數字交錯出現,這表明它們是在同時運行的!

方法2:繼承Thread類

這種方法涉及創建一個Thread類的子類,並覆寫它的run()方法。這裡有一個例子:

public class MyThread extends Thread {
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println("繼承Thread類的線程: " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("線程被中斷。");
            }
        }
    }

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

        // 主線程
        for (int i = 1; i <= 5; i++) {
            System.out.println("主線程: " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("主線程被中斷。");
            }
        }
    }
}

這裡的主要區別在於:

  1. 我們的類MyThread繼承了Thread而不是實現Runnable
  2. 我們可以直接在我們的MyThread對象上調用start(),而不需要創建一個Thread實例。

比較兩種方法

兩種方法都能達到相同的效果,但有一些考慮:

特性 Runnable接口 繼承Thread類
靈活性 可以繼承其他類 不能繼承其他類(Java不支持多重繼承)
關心點分離 將任務從線程中分離 將任務和線程合並在同一個類中
可重用性 更可重用 較少可重用
資源效率 更高效(可以與線程池一起使用) 較低效率

在大多數情況下,實現Runnable被認為是更好的實踐,因為它提供了更多的靈活性並更好地符合面向對象設計的原則。

結論

恭喜你!你剛剛踏入了Java線程世界的第一步。我們已經介紹了線程的基本知識,它們有什麼用,以及如何使用兩種不同的方法來創建它們。記住,就像學習擲骰子一樣,掌握線程需要練習。如果它們立即不能引起你的共鳴——不要氣餒,繼續嘗試,你會達到的!

在我下一次的課程中,我們將深入探討線程同步和線程之間的通信。在那之前,祝你編程愉快,願你的線程總是運行順暢!

Credits: Image by storyset