實現多執行緒的四種方式
阿新 • • 發佈:2020-11-19
二
package com.aaa.threaddemo; /* * 一 實現多執行緒有哪四種方式? * 1.繼承Thread類 * 2.實現runnable介面 * */ public class CreatThreadMethod { public static void main(String[] args) { Demo2 thread2 = new Demo2(); //例項化 我們的demo2 thread Thread thread = new Thread(thread2); //把new的 demo2 thread 物件,放入Thread中 ,然後開啟start方法。 thread.start(); } } /* * 1 繼承一個thread類 * thread是runnable的實現類,代表一個執行緒的例項。 * 裡面有個一個native方法 start()方法,他可以啟動一個新的執行緒, * 並執行run方法 */ class Demo1 extends Thread{ @Override public void run() { System.out.println("繼承thread 重寫run方法 呼叫start, 開啟一個多執行緒"); } } /* * 二 實現runnable介面 * 注意!Java中只有單繼承機制,已經有繼承的子類如何實現多執行緒? * 可以考慮runnable介面。 * * 當我們的例項物件demo2實現runnable介面之後,還需要new一個Thread, * 把 demo2 當做target 傳入到Thread中,才能呼叫star方法,開啟多執行緒。 */ class Demo2 extends CreatThreadMethod implementsRunnable{ @Override public void run() { System.out.println("在繼承的基礎上,實現runnable介面,開啟多執行緒"); } }
三 有返回值的執行緒?
package com.aaa.threaddemo; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /* * 一 實現多執行緒有哪四種方式? * 1.繼承Thread類 * 2.實現runnable介面 * 3.ExecutorService、Callable<Class>、Future 有返回值執行緒 * */ public class CreatThreadMethod { public static void main(String[] args) { Demo2 thread2 = new Demo2(); //例項化 我們的demo2 thread Thread thread = new Thread(thread2); //把new的 demo2 thread 物件,放入Thread中 ,然後開啟start方法。 thread.start(); } } /* * 1 繼承一個thread類 * thread是runnable的實現類,代表一個執行緒的例項。 * 裡面有個一個native方法 start()方法,他可以啟動一個新的執行緒, * 並執行run方法 */ class Demo1 extends Thread{ @Override public void run() { System.out.println("繼承thread 重寫run方法 呼叫start, 開啟一個多執行緒"); } } /* * 二 實現runnable介面 * 注意!Java中只有單繼承機制,已經有繼承的子類如何實現多執行緒? * 可以考慮runnable介面。 * * 當我們的例項物件demo2實現runnable介面之後,還需要new一個Thread, * 把 demo2 當做target 傳入到Thread中,才能呼叫star方法,開啟多執行緒。 */ class Demo2 extends CreatThreadMethod implements Runnable{ @Override public void run() { System.out.println("在繼承的基礎上,實現runnable介面,開啟多執行緒"); } } /* * 三 有返回值執行緒? * 在方法二中,我們實現的是runnable介面,這是一個沒有返回值的介面,那麼如果我是想要有返回值如何處理? * 實現callable介面 * * 執行callable後 可以獲取一個future物件,在該物件呼叫get,就能獲取到callable任務的object。 * 再結合executor service 介面, 即可實現有返回結果的多執行緒 * * newFixedThreadPool 建立一個固定的執行緒池 */ class CallableFuture { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService pool = Executors.newFixedThreadPool(2); //newFixedThreadPool(); 建立一個固定的執行緒池 2 個 Demo3 threa1 = new Demo3("我是執行緒1,實現了callable介面"); //demo3 實現了callable介面 Demo3 threa2 = new Demo3("我是執行緒2"); Future future1 = pool.submit(threa1); //通過executor.submit提交一個Callable,返回一個Future,然後通過這個Future的get方法取得返回值。 Future future2 = pool.submit(threa2); System.out.println(future1.get()); //Future 的get方法 獲得返回值。 System.out.println(future2.get()); pool.shutdown(); //關閉執行緒池 } } /* ExecutorService 介面? <T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task); 一 callable 和 runnable介面的區別 public interface Callable<V> { V call() throws Exception; } 可以看到在callable裡面, 有一個泛型V call方法中返回一個這個型別的值 interface Runnable { public abstract void run(); } runnable 這裡是沒有返回值的 二 Future 是個啥? public interface Future<V> { boolean cancel(boolean var1); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long var1, TimeUnit var3) throws InterruptedException, ExecutionException, TimeoutException; } Future 也是一個介面,使用它的get()方法,可以獲得任務執行的返回值。 */ class Demo3 implements Callable<Object>{ private String threadName; public Demo3(String threadName) { this.threadName = threadName; } @Override public Object call() throws Exception { return "[threaName=" + threadName + "]" + "返回的資訊"; } }
四 執行緒池的方式
package com.aaa.threaddemo; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /* * 一 實現多執行緒有哪四種方式? * 1.繼承Thread類 * 2.實現runnable介面 * 3.ExecutorService、Callable<Class>、Future 有返回值執行緒 * 4.基於執行緒池的方式 * */ public class CreatThreadMethod { public static void main(String[] args) { Demo2 thread2 = new Demo2(); //例項化 我們的demo2 thread Thread thread = new Thread(thread2); //把new的 demo2 thread 物件,放入Thread中 ,然後開啟start方法。 thread.start(); } } /* * 1 繼承一個thread類 * thread是runnable的實現類,代表一個執行緒的例項。 * 裡面有個一個native方法 start()方法,他可以啟動一個新的執行緒, * 並執行run方法 */ class Demo1 extends Thread{ @Override public void run() { System.out.println("繼承thread 重寫run方法 呼叫start, 開啟一個多執行緒"); } } /* * 二 實現runnable介面 * 注意!Java中只有單繼承機制,已經有繼承的子類如何實現多執行緒? * 可以考慮runnable介面。 * * 當我們的例項物件demo2實現runnable介面之後,還需要new一個Thread, * 把 demo2 當做target 傳入到Thread中,才能呼叫star方法,開啟多執行緒。 */ class Demo2 extends CreatThreadMethod implements Runnable{ @Override public void run() { System.out.println("在繼承的基礎上,實現runnable介面,開啟多執行緒"); } } /* * 三 有返回值執行緒? * 在方法二中,我們實現的是runnable介面,這是一個沒有返回值的介面,那麼如果我是想要有返回值如何處理? * 實現callable介面 * * 執行callable後 可以獲取一個future物件,在該物件呼叫get,就能獲取到callable任務的object。 * 再結合executor service 介面, 即可實現有返回結果的多執行緒 * * newFixedThreadPool 建立一個固定的執行緒池 */ class CallableFuture { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService pool = Executors.newFixedThreadPool(2); //newFixedThreadPool(); 建立一個固定的執行緒池 2 個 Demo3 threa1 = new Demo3("我是執行緒1,實現了callable介面"); //demo3 實現了callable介面 Demo3 threa2 = new Demo3("我是執行緒2"); Future future1 = pool.submit(threa1); //通過executor.submit提交一個Callable,返回一個Future,然後通過這個Future的get方法取得返回值。 Future future2 = pool.submit(threa2); System.out.println(future1.get()); //Future 的get方法 獲得返回值。 System.out.println(future2.get()); pool.shutdown(); //關閉執行緒池 } } /* ExecutorService 介面? <T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task); 一 callable 和 runnable介面的區別 public interface Callable<V> { V call() throws Exception; } 可以看到在callable裡面, 有一個泛型V call方法中返回一個這個型別的值 interface Runnable { public abstract void run(); } runnable 這裡是沒有返回值的 二 Future 是個啥? public interface Future<V> { boolean cancel(boolean var1); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long var1, TimeUnit var3) throws InterruptedException, ExecutionException, TimeoutException; } Future 也是一個介面,使用它的get()方法,可以獲得任務執行的返回值。 */ class Demo3 implements Callable<Object>{ private String threadName; public Demo3(String threadName) { this.threadName = threadName; } @Override public Object call() throws Exception { return "[threaName=" + threadName + "]" + "返回的資訊"; } } /* * 為啥使用執行緒池? * 1 資源的寶貴性 一個執行緒系統中的建立是一個複雜的過程。 * 2 便於管理 提高效率 * 3 快取的策略 執行緒池 * * */ class ThreadPool{ public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(5); //建立一個執行緒池 固定容量是5 while(true){ pool.execute(new Runnable() { //提交多個執行緒任務 並執行 @Override public void run() { System.out.println( "當前執行緒【" +Thread.currentThread().getName() + "】 正在執行"); try { Thread.sleep(3000); //讓執行緒睡一會 } catch (InterruptedException e) { e.printStackTrace(); } } }); } } }