Table of Contents
ToggleDifference Between Thread and Runnable in Java
多執行緒實現同時執行多任務,有兩種方式可以實現,一個是繼承 Thread ,覆寫 run 方法,另一個是實作 Runnable 介面,Difference Between Runnable and Thread in Java 提供這兩種應用方式,本篇增加了範例,並透過單元測試來驗證產出結果。
檔案目錄
./
+- src
+- test
| +- org
| +- ruoxue
| +- java_147
| +- multithreading
| +- runnable
| +- DifferenceThreadRunnableTest.java
單元測試
Difference Between Thread and Runnable in Java 提供執行任務等操作。
task
Difference Between Thread and Runnable 繼承 Thread ,覆寫 run 方法,建立 1 條執行緒,執行 1 個任務,每個任務耗時 3 秒完成。
protected class Task extends Thread {
@Override
public void run() {
try {
System.out.println("T[" + Thread.currentThread().getId() + "] worker: ready");
TimeUnit.SECONDS.sleep(3);
System.out.println("T[" + Thread.currentThread().getId() + "] worker: finished");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
@Test
public void task() {
Thread thread = new Task();
thread.start();
try {
thread.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
T[11] worker: ready
T[11] worker: finished
worker
Difference Between Thread and Runnable 繼承自定義物件,並實作 Runnable 建立 1 條執行緒,執行 1 個任務,每個任務耗時 3 秒完成。
protected class Obj {
private String name;
public Obj(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
protected class Worker extends Obj implements Runnable {
public Worker(String name) {
super(name);
}
@Override
public void run() {
try {
System.out.println("T[" + Thread.currentThread().getId() + "] worker " + getName() + ": ready");
TimeUnit.SECONDS.sleep(3);
System.out.println("T[" + Thread.currentThread().getId() + "] worker " + getName() + ": finished");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
@Test
public void worker() {
Worker worker = new Worker("AAA");
Thread thread = new Thread(worker);
thread.start();
try {
thread.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
T[11] worker AAA: ready
T[11] worker AAA: finished
threadsWorker
Difference Between Thread and Runnable 繼承自定義物件,並實作 Runnable ,建立 3 條執行緒,執行相同任務,每個任務耗時 3 秒完成。
@Test
public void threadsWorker() {
try {
int taskSize = 3;
Worker worker = new Worker("BBB");
List<Thread> threads = new ArrayList<Thread>();
IntStream.range(0, taskSize).forEach(e -> {
Thread thread = new Thread(worker);
thread.start();
threads.add(thread);
});
threads.forEach(e -> {
try {
e.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
T[11] worker BBB: ready
T[13] worker BBB: ready
T[12] worker BBB: ready
T[12] worker BBB: finished
T[13] worker BBB: finished
T[11] worker BBB: finished
DifferenceThreadRunnableTest.java
Difference Between Runnable and Thread 新增單元測試,驗證是否符合預期。
package org.ruoxue.java_147.multithreading.runnable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import org.junit.Test;
public class DifferenceThreadRunnableTest {
protected class Task extends Thread {
@Override
public void run() {
try {
System.out.println("T[" + Thread.currentThread().getId() + "] worker: ready");
TimeUnit.SECONDS.sleep(3);
System.out.println("T[" + Thread.currentThread().getId() + "] worker: finished");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
@Test
public void task() {
Thread thread = new Task();
thread.start();
try {
thread.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
protected class Obj {
private String name;
public Obj(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
protected class Worker extends Obj implements Runnable {
public Worker(String name) {
super(name);
}
@Override
public void run() {
try {
System.out.println("T[" + Thread.currentThread().getId() + "] worker " + getName() + ": ready");
TimeUnit.SECONDS.sleep(3);
System.out.println("T[" + Thread.currentThread().getId() + "] worker " + getName() + ": finished");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
@Test
public void worker() {
Worker worker = new Worker("AAA");
Thread thread = new Thread(worker);
thread.start();
try {
thread.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
@Test
public void threadsWorker() {
try {
int taskSize = 3;
Worker worker = new Worker("BBB");
List<Thread> threads = new ArrayList<Thread>();
IntStream.range(0, taskSize).forEach(e -> {
Thread thread = new Thread(worker);
thread.start();
threads.add(thread);
});
threads.forEach(e -> {
try {
e.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
心得分享
Difference Between Thread and Runnable Interface in Java 的區別:
Thread Class | Runnable Interface |
---|---|
是一個類別 | 是一個介面 |
有很多種方法,包含 start 、run 方法 | 只有一個抽象方法 run |
每一個執行緒建立一個物件並與之相關 | 多個執行緒可以共享同一物件 |
需要更多記憶體 | 需要較少記憶體 |
繼承後,無法再繼承其他物件 | 實作介面,可以繼承其他物件 |