最近在學習併發,因而我在網上搜了一本《java併發編程實戰》書學習。java
在我印象中建立線程有兩種方式編程
1. 繼承Thread類,重寫run方法,實例化本身寫Thread子類,並用start()方法開啓。緩存
2.實現Runnable接口,重寫run方法,把Runnable的子類的實例對象做爲Thread的構造參數傳遞進去,建立線程,並開啓。併發
可是我看別人代碼時大部分都用第一種方式,直接new Thread 而後重寫run方法。其實第二種方式更加符合面向對象的編程,由於,Thread是一個線程,他只管建立和開啓線程,而不該該進行邏輯的處理代碼寫到裏面,邏輯處理應該交給Runnable的子類的進行。ide
傳統定時器是Timer類,建立方式工具
Timer timer = new Timer(); timer.schedule(new TimerTask(){ //建立定時器任務 @Override public void run() { System.out.println("你好"); } },2000); //2秒以後打印你好 timer.schedule(new TimerTask(){ @Override public void run() { System.out.println("你好"); } },2000,3000); //2秒以後打印你好,接着每3秒打印一次你好。
此處有個要求,須要在2以後打印你好,3秒以後打印世界...,而後不斷的循環打印下去。該怎麼辦?oop
思路:1.我能夠建立兩個定時器任務,task1任務2秒後打印你好,task2任務3秒後打印,而後在task1任務結束時開啓task2,在task2結束時開啓task1學習
2.能夠只建立一個task ,讓後在外部作一個 flag標記,當爲true是執行打印你好,而後在結束時開啓一個新任務,並把flag=!flag;
spa
//第一種實現 public static void main(String[] args) { new Timer().schedule(new MyTimerTask1(), 2000); while (true) { System.out.println(new Date().getSeconds()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } static class MyTimerTask1 extends TimerTask { @Override public void run() { System.out.println("hello"); new Timer().schedule(new MyTimerTask2(), 3000); } } static class MyTimerTask2 extends TimerTask { @Override public void run() { System.out.println("wrold"); new Timer().schedule(new MyTimerTask1(), 2000); } } }
第二種能夠就不貼了。線程
使用Executors工具類進行建立線程池
API的介紹:
newFixedThreadPool 建立一個固定長度的線程池,當到達線程最大數量時,線程池的規模將再也不變化。
newCachedThreadPool 建立一個可緩存的線程池,若是當前線程池的規模超出了處理需求,將回收空的線程;當需求增長時,會增長線程數量;線程池規模無限制。
newSingleThreadPoolExecutor 建立一個單線程的Executor,確保任務對了,串行執行(此單個線程死以後又會有個線程代替他)
public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(3); //第1種 // ExecutorService threadPool = Executors.newCachedThreadPool();//第2種 // ExecutorService threadPool = Executors.newSingleThreadExecutor();//第3種 for (int i = 1; i <= 10; i++) { final int task = i; threadPool.execute(new Runnable() { @Override public void run() { for (int j = 1; j <= 5; j++) { try { Thread.sleep(20); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " is looping of " + j + " for task of " + task); } } }); } }
把10個任務交個3種線程池去完成,
結果
第1種的結果 10個任務只有個開起固定的3個線程去完成任務 pool-1-thread-1 is looping of 1 for task of 1 pool-1-thread-3 is looping of 1 for task of 3 pool-1-thread-2 is looping of 1 for task of 2 pool-1-thread-1 is looping of 2 for task of 1 pool-1-thread-2 is looping of 2 for task of 2 pool-1-thread-3 is looping of 2 for task of 3 pool-1-thread-2 is looping of 1 for task of 6 pool-1-thread-1 is looping of 1 for task of 4 pool-1-thread-3 is looping of 1 for task of 5 pool-1-thread-3 is looping of 2 for task of 5 pool-1-thread-3 is looping of 3 for task of 3 pool-1-thread-2 is looping of 4 for task of 2 第2種的結果 10個任務開起了10個線程去完成 pool-1-thread-1 is looping of 1 for task of 1 pool-1-thread-3 is looping of 1 for task of 3 pool-1-thread-2 is looping of 1 for task of 2 pool-1-thread-9 is looping of 1 for task of 9 pool-1-thread-10 is looping of 1 for task of 10 pool-1-thread-6 is looping of 1 for task of 6 pool-1-thread-5 is looping of 1 for task of 5 pool-1-thread-4 is looping of 1 for task of 4 pool-1-thread-8 is looping of 1 for task of 8 pool-1-thread-7 is looping of 1 for task of 7 pool-1-thread-3 is looping of 2 for task of 3 pool-1-thread-1 is looping of 2 for task of 1 pool-1-thread-2 is looping of 2 for task of 2 pool-1-thread-7 is looping of 2 for task of 7 pool-1-thread-4 is looping of 2 for task of 4 pool-1-thread-5 is looping of 2 for task of 5 pool-1-thread-9 is looping of 2 for task of 9 pool-1-thread-8 is looping of 2 for task of 8 pool-1-thread-6 is looping of 2 for task of 6 pool-1-thread-10 is looping of 2 for task of 10 第3種的結果 10個任務卻只開啓了一個線程 pool-1-thread-1 is looping of 1 for task of 1 pool-1-thread-1 is looping of 2 for task of 1 pool-1-thread-1 is looping of 1 for task of 2 pool-1-thread-1 is looping of 2 for task of 2 pool-1-thread-1 is looping of 1 for task of 3 pool-1-thread-1 is looping of 2 for task of 3 pool-1-thread-1 is looping of 1 for task of 4 pool-1-thread-1 is looping of 2 for task of 4 pool-1-thread-1 is looping of 1 for task of 5 pool-1-thread-1 is looping of 2 for task of 5 pool-1-thread-1 is looping of 1 for task of 6 pool-1-thread-1 is looping of 2 for task of 6 pool-1-thread-1 is looping of 1 for task of 7 pool-1-thread-1 is looping of 2 for task of 7 pool-1-thread-1 is looping of 1 for task of 8 pool-1-thread-1 is looping of 2 for task of 8 pool-1-thread-1 is looping of 1 for task of 9 pool-1-thread-1 is looping of 2 for task of 9 pool-1-thread-1 is looping of 1 for task of 10 pool-1-thread-1 is looping of 2 for task of 10
newScheduledThreadPool是建立定時器 和Timer差很少,但Timer內部只有一個線程進行執行任務,而newScheduledThreadPool是能夠設置多個線程的
Executors.newScheduledThreadPool(3).scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("bombing!"); } }, 6, 2, TimeUnit.SECONDS);