java併發之線程的建立(一)

  1.    概論

    最近在學習併發,因而我在網上搜了一本《java併發編程實戰》書學習。java

  2.   傳統建立線程的方式(jdk 1.5以前的方式)

    在我印象中建立線程有兩種方式編程

    1. 繼承Thread類,重寫run方法,實例化本身寫Thread子類,並用start()方法開啓。緩存

    2.實現Runnable接口,重寫run方法,把Runnable的子類的實例對象做爲Thread的構造參數傳遞進去,建立線程,並開啓。併發

    可是我看別人代碼時大部分都用第一種方式,直接new Thread 而後重寫run方法。其實第二種方式更加符合面向對象的編程,由於,Thread是一個線程,他只管建立和開啓線程,而不該該進行邏輯的處理代碼寫到裏面,邏輯處理應該交給Runnable的子類的進行。ide

  3.  傳統建立定時器的方式

    傳統定時器是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);
相關文章
相關標籤/搜索