1. 程式人生 > >多執行緒的實現方式

多執行緒的實現方式

多執行緒是指 一個程式執行時,產生或使用了不止一個執行緒。

執行緒的生命週期是怎麼樣的,下面這張圖我們可以看出些端倪:

這章我們主要討論多執行緒實現的方式,基礎知識部分我們可以下來再惡補。

方法一:Runnable 介面實現:

繼承介面,實現業務邏輯:

public class WorkRunnable implements Runnable {
   private String taskName;
   public WorkRunnable(String taskName) {
      this.taskName = taskName;
   }
   @Override
public 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 int                
CORE_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);
   }
}