Difference Between Thread and Runnable in Java - Java 147

Difference Between Thread and Runnable in Java – Java 147

Difference 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 ClassRunnable Interface
是一個類別是一個介面
有很多種方法,包含 start 、run 方法只有一個抽象方法 run
每一個執行緒建立一個物件並與之相關多個執行緒可以共享同一物件
需要更多記憶體需要較少記憶體
繼承後,無法再繼承其他物件實作介面,可以繼承其他物件

發佈留言