多線程是指 一個程序運行時,產生或使用了不止一個線程。java
線程的生命週期是怎麼樣的,下面這張圖咱們能夠看出些端倪:多線程
這章咱們主要討論多線程實現的方式,基礎知識部分咱們能夠下來再惡補。ide
方法一:Runnable 接口實現:this
繼承接口,實現業務邏輯:spa
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; } }
實現多線程任務的調用:code
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實現:blog
這種方式的實現,在我前一篇文章中已有提到,這裏再也不單獨討論。繼承
方法三: 實現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); } }