1. 程式人生 > >多執行緒(4)-執行緒池

多執行緒(4)-執行緒池

Java5之後提供了執行緒池ThreadPool,

concurrent包下的Executors提供了很多建立執行緒池的方法,根據不同需要,分開使用。包括但不限於
newFixedThreadPool固定大小的執行緒池,newCachedThreadPool快取執行緒池(根據執行緒多少建立執行緒數),newSingleThreadExecutor單執行緒(保證有一個執行緒),newScheduledThreadPool(定時器執行緒池).....

上程式碼

public class ThreadPoolTest {

	public static void main(String[] args) {
		//ExecutorService threadPool = Executors.newFixedThreadPool(3);
		//ExecutorService threadPool = Executors.newCachedThreadPool();
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		for(int i=1;i<=10;i++){
			final int task = i;
			threadPool.execute(new Runnable(){
				@Override
				public void run() {
					for(int j=1;j<=10;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);
					}
				}
			});
		}
		System.out.println("all of 10 tasks have committed! ");
		//threadPool.shutdownNow();
		
		Executors.newScheduledThreadPool(3).scheduleAtFixedRate(
				new Runnable(){
					@Override
				public void run() {
					System.out.println("bombing!");
					
				}},
				6,
				2,
				TimeUnit.SECONDS);
	}
}

實際程式碼要注意使用try catch finally,根據需要在finally裡關閉執行緒池。上述程式碼在jdk1.8之後使用lambda表示式後為

public class ThreadPoolTest {

	public static void main(String[] args) {
		//ExecutorService threadPool = Executors.newFixedThreadPool(3);
		//ExecutorService threadPool = Executors.newCachedThreadPool();
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		for(int i=1;i<=10;i++){
			final int task = i;
			threadPool.execute(() -> {
                for(int j=1;j<=10;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);
                }
            });
		}
		System.out.println("all of 10 tasks have committed! ");
		//threadPool.shutdownNow();
		
		Executors.newScheduledThreadPool(3).scheduleAtFixedRate(
				() -> System.out.println("bombing!"),
				6,
				2,
				TimeUnit.SECONDS);
	}
}

當有返回結果時,使用callable和future代替runnable

上程式碼學姿勢

ExecutorService threadPool =  Executors.newSingleThreadExecutor();
		Future<String> future =
			threadPool.submit(
					() -> {
						Thread.sleep(2000);
						return "hello";
					}
			);
		System.out.println("等待結果");
		try {
			System.out.println("拿到結果:" + future.get());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

當有一組Callable任務需要提交時,使用CompletionService,期take()方法返回對應的Future物件

上程式碼

ExecutorService threadPool2 =  Executors.newFixedThreadPool(10);
		CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
		for(int i=1;i<=10;i++){
			final int seq = i;
			completionService.submit(() -> {
                Thread.sleep(new Random().nextInt(5000));
                return seq;
            });
		}
		for(int i=0;i<10;i++){
			try {
				System.out.println(
						completionService.take().get());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}