下午在調試多線程時發現,雖然確認每次都是將線程池關閉java
executor.shutdown(); executor.awaitTermination(1, TimeUnit.SECONDS)
可是第二個調用任務進來線程池序號仍是增長了,沒找到緣由。當時想了兩種解決方法,第一種是用spring來管理線程池,第二種是使用單列模式。看了下網上關於使用spring管理線程池的代碼,考慮到我這個功能並無這麼重量級,須要改配置文件來處理。簡單處理,使用單列模式作。spring
1.建立自定義名稱的線程池多線程
package com.demo.thread.test20170811; import java.util.concurrent.BlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * 自定義名稱線程池 * @author fsw * */ public class NamedThreadPoolExecutor extends ThreadPoolExecutor{ private String name; public NamedThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
2.建立單列模式ide
package com.demo.thread.test20170811; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; /** * 線程池管理類 * @author fsw * */ public class SingletonThreadPool { final NamedThreadPoolExecutor executor = new NamedThreadPoolExecutor(5,5,0,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(5), new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { NamedThreadPoolExecutor namedThreadPoolExe = (NamedThreadPoolExecutor) executor; try { System.out.println(namedThreadPoolExe.getName()); executor.getQueue().put(r); } catch (Exception e) { } } }); private static SingletonThreadPool threadPool = null; private static ReentrantLock lock = new ReentrantLock(); public static SingletonThreadPool getInstance() { try { lock.lock(); if(threadPool == null) { threadPool = new SingletonThreadPool(); return threadPool; } } finally { lock.unlock(); } return threadPool; } public ExecutorService getExecutorService(String name) { executor.setName(name); return executor; } public Long getComTaskCount() { return executor.getCompletedTaskCount(); } }
3.建立執行任務類測試
package com.demo.thread.test20170811; import java.util.concurrent.Callable; public class Task implements Callable<Void>{ @Override public Void call() throws Exception { System.out.println(Thread.currentThread().getName()); return null; } }
4.測試類this
package com.demo.thread.test20170811; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; public class SingletonThreadMain { public static void main(String[] args) throws InterruptedException, ExecutionException { final SingletonThreadMain m = new SingletonThreadMain(); m.runMethod("a"); m.runMethod("b"); m.runMethod("c"); } public void runMethod(final String name) throws InterruptedException, ExecutionException { SingletonThreadPool threadPool = SingletonThreadPool.getInstance(); CompletionService<Void> completionService = new ExecutorCompletionService<Void>( threadPool.getExecutorService(name)); for (int i = 0; i < 100; i++) { completionService.submit(new Task()); } for (int i = 0; i < 100; i++) { completionService.take().get(); } System.out.println("==================="+SingletonThreadPool.getInstance().getComTaskCount()); } }
5.執行結果線程
從執行結果可見,線程池序號一直都是1。問題初步解決,後面遇到問題再更新調試