標籤:
- 概論
最近在學習並發,於是我在網上搜了一本《java並發編程實戰》書學習。
- 傳統建立線程的方式(jdk 1.5之前的方式)
在我印象中建立線程有兩種方式
1. 繼承Thread類,重寫run方法,執行個體化自己寫Thread子類,並用start()方法開啟。
2.實現Runnable介面,重寫run方法,把Runnable的子類的執行個體對象作為Thread的構造參數傳遞進去,建立線程,並開啟。
但是我看別人代碼時大部分都用第一種方式,直接new Thread 然後重寫run方法。其實第二種方式更加符合物件導向的編程,因為,Thread是一個線程,他只管建立和開啟線程,而不應該進行邏輯的處理代碼寫到裡面,邏輯處理應該交給Runnable的子類的進行。
- 傳統建立定時器的方式
傳統定時器是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秒之後列印世界...,然後不斷的迴圈列印下去。該怎麼辦?
思路:1.我可以建立兩個定時器任務,task1任務2秒後列印你好,task2任務3秒後列印,然後在task1任務結束時開啟task2,在task2結束時開啟task1
2.可以只建立一個task ,讓後在外部做一個 flag標記,當為true是執行列印你好,然後在結束時開啟一個新任務,並把flag=!flag;
//第一種實現 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 blocke.printStackTrace();}}}static class MyTimerTask1 extends TimerTask {@Overridepublic void run() {System.out.println("hello");new Timer().schedule(new MyTimerTask2(), 3000);}}static class MyTimerTask2 extends TimerTask {@Overridepublic 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() {@Overridepublic void run() {for (int j = 1; j <= 5; j++) {try {Thread.sleep(20);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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 1pool-1-thread-3 is looping of 1 for task of 3pool-1-thread-2 is looping of 1 for task of 2pool-1-thread-1 is looping of 2 for task of 1pool-1-thread-2 is looping of 2 for task of 2pool-1-thread-3 is looping of 2 for task of 3pool-1-thread-2 is looping of 1 for task of 6pool-1-thread-1 is looping of 1 for task of 4pool-1-thread-3 is looping of 1 for task of 5pool-1-thread-3 is looping of 2 for task of 5pool-1-thread-3 is looping of 3 for task of 3pool-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 1pool-1-thread-3 is looping of 1 for task of 3pool-1-thread-2 is looping of 1 for task of 2pool-1-thread-9 is looping of 1 for task of 9pool-1-thread-10 is looping of 1 for task of 10pool-1-thread-6 is looping of 1 for task of 6pool-1-thread-5 is looping of 1 for task of 5pool-1-thread-4 is looping of 1 for task of 4pool-1-thread-8 is looping of 1 for task of 8pool-1-thread-7 is looping of 1 for task of 7pool-1-thread-3 is looping of 2 for task of 3pool-1-thread-1 is looping of 2 for task of 1pool-1-thread-2 is looping of 2 for task of 2pool-1-thread-7 is looping of 2 for task of 7pool-1-thread-4 is looping of 2 for task of 4pool-1-thread-5 is looping of 2 for task of 5pool-1-thread-9 is looping of 2 for task of 9pool-1-thread-8 is looping of 2 for task of 8pool-1-thread-6 is looping of 2 for task of 6pool-1-thread-10 is looping of 2 for task of 10第3種的結果 10個任務卻只開啟了一個線程pool-1-thread-1 is looping of 1 for task of 1pool-1-thread-1 is looping of 2 for task of 1pool-1-thread-1 is looping of 1 for task of 2pool-1-thread-1 is looping of 2 for task of 2pool-1-thread-1 is looping of 1 for task of 3pool-1-thread-1 is looping of 2 for task of 3pool-1-thread-1 is looping of 1 for task of 4pool-1-thread-1 is looping of 2 for task of 4pool-1-thread-1 is looping of 1 for task of 5pool-1-thread-1 is looping of 2 for task of 5pool-1-thread-1 is looping of 1 for task of 6pool-1-thread-1 is looping of 2 for task of 6pool-1-thread-1 is looping of 1 for task of 7pool-1-thread-1 is looping of 2 for task of 7pool-1-thread-1 is looping of 1 for task of 8pool-1-thread-1 is looping of 2 for task of 8pool-1-thread-1 is looping of 1 for task of 9pool-1-thread-1 is looping of 2 for task of 9pool-1-thread-1 is looping of 1 for task of 10pool-1-thread-1 is looping of 2 for task of 10
newScheduledThreadPool是建立定時器 和Timer差不多,但Timer內部只有一個線程進行執行任務,而newScheduledThreadPool是可以設定多個線程的
Executors.newScheduledThreadPool(3).scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println("bombing!");}}, 6, 2, TimeUnit.SECONDS);
java並發之線程的建立(一)