多執行緒的實現方式
阿新 • • 發佈:2018-12-14
多執行緒是指 一個程式執行時,產生或使用了不止一個執行緒。
執行緒的生命週期是怎麼樣的,下面這張圖我們可以看出些端倪:
這章我們主要討論多執行緒實現的方式,基礎知識部分我們可以下來再惡補。
方法一:Runnable 介面實現:
繼承介面,實現業務邏輯:
public class WorkRunnable implements Runnable { private String taskName; public WorkRunnable(String taskName) { this.taskName = taskName; } @Overridepublic void run() { System.out.println("開始執行任務" + taskName); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(taskName + "任務執行完成"); } }
初始化一個執行緒池,來呼叫任務:
public class ThreadPool { private static final intCORE_SIZE = 8; private static final int MAX_SIZE = 12; private static final long KEEP_ALIVE_TIME = 30; private static final int QUEUE_SIZE = 50000; private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(CORE_SIZE, MAX_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(QUEUE_SIZE), new ThreadPoolExecutor.AbortPolicy()); public static ThreadPoolExecutor getThreadPool() { return threadPool; } }
實現多執行緒任務的呼叫:
public class RunnableClient { public static void main(String[] args) { WorkRunnable runnable1 = new WorkRunnable("taskName1"); WorkRunnable runnable2 = new WorkRunnable("taskName2"); ThreadPoolExecutor executor = ThreadPool.getThreadPool(); executor.execute(runnable1); executor.execute(runnable2); } }
方法二:繼承Thread實現:
這種方式的實現,在我前一篇文章中已有提到,這裡不再單獨討論。
方法三: 實現Callable介面,這是一個帶返回值的實現方式:
看任務定義:
public class WorkCallable implements Callable<String> { private String taskName; public WorkCallable(String taskName) { this.taskName = taskName; } @Override public String call() throws Exception { System.out.println(taskName + "開始執行"); Thread.sleep(2000); System.out.println(taskName + "結束執行"); return taskName; } }
再來看主執行緒中如何呼叫:
public class CallableClient { public static void main(String[] args) throws ExecutionException, InterruptedException { WorkCallable task1 = new WorkCallable("task1"); WorkCallable task2 = new WorkCallable("task2"); FutureTask<String> task11 = new FutureTask<String>(task1); FutureTask<String> task22 = new FutureTask<String>(task2); Thread t1 = new Thread(task11); Thread t2 = new Thread(task22); t1.start(); t2.start(); System.out.println("task1的執行結果:" + task11.get()); System.out.println("task2的執行結果:" + task22.get()); } }
執行程式碼,看下執行結果如何:
task1開始執行 task2開始執行 task2結束執行 task1結束執行 task1的執行結果:task1 task2的執行結果:task2
方法四:使用定時器,就是繼承TimerTask 類:
翻看JDK的原始碼,可以看到,TimerTask 是一個實現了 Runnable 介面的抽象類,所以它跟Runnable介面的實現方式本質上是一樣的。
任務實現類:
public class WorkTimer extends TimerTask { private String taskName; public WorkTimer(String taskName) { this.taskName = taskName; } @Override public void run() { System.out.println(taskName + "任務開始執行"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(taskName + "任務執行結束"); } }
主執行緒:
public class TimerClient { public static void main(String[] args) { WorkTimer task1 = new WorkTimer("task1"); WorkTimer task2 = new WorkTimer("task2"); Timer timer = new Timer(); timer.schedule(task1,2000); timer.schedule(task2, 3000); } }