多執行緒(4)-執行緒池
阿新 • • 發佈:2018-12-20
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();
}
}