java终止运行时间超时的线程代码
因为现在我要监控远程的一个方法,当这个方法执行超过一段时间时,我就要抛弃这个任务.那个方法我不能修改 测试代码
Java code?public class MyThreadPool{ private static MyThreadPool myThreadPool = null; /*** 线程的最小数*/ private static int corePoolSize = 5; private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize*2,10,TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(corePoolSize),new ThreadPoolExecutor.AbortPolicy()); private MyThreadPool(){} public static MyThreadPool getInstance(){ if(null == myThreadPool){ System.out.println("MyThreadPool is creating!"); myThreadPool = new MyThreadPool(); } return myThreadPool; } /** * 执行任务 */ public void exeWork(final MyWork work,int availableTime){ FutureTask<Boolean> future = new FutureTask<Boolean>(new Callable<Boolean>(){ public Boolean call(){ return work.doSometing(); } }); executor.execute(future); try{ future.get(availableTime, TimeUnit.SECONDS); }catch(ExecutionException e1){ e1.printStackTrace(); }catch(InterruptedException e2){ e2.printStackTrace(); }catch(TimeoutException e3){ System.out.println("执行任务超时!"); }finally{ future.cancel(true); closeExecutor(); } } public void closeExecutor(){ if(executor != null && executor.getActiveCount() ==0 && executor.getQueue().isEmpty()){ executor.shutdown(); } } public static int getCorePoolSize() { return corePoolSize; } public static void setCorePoolSize(int corePoolSize) { MyThreadPool.corePoolSize = corePoolSize; } }
Main 方法
Java code?public static void main(String[] args){ MyThreadPool threadPool = MyThreadPool.getInstance(); int availableTime = 5; MyWork b = new BWork(); threadPool.exeWork(b, availableTime);
Java code?public class BWork implements MyWork{ public boolean doSometing(){ System.out.println("B starting..."); //模拟远程的方法 最坏的情况是死循环 while(true){ } } } 这段代码已经可以停止超时任务了。
但是closeExecutor()方法里面不应该判断executor.getActiveCount() ==0。
ThreadPoolExecutor的核心线程数以内的线程是不会被收回的,只有超过你设置的核心线程数的线程才会被收回,所以你的ThreadPoolExecutor对象只要执行过任务,executor.getActiveCount()就一定不会是0。
你这样写就一定不会执行shutdown方法
worker 最好以以下的形式进行循环
Java code?while (true) { if (Thread.currentThread().isInterrupted()) { return; } // do something // thread sleep }
这样打断该线程,以便结束该线程的生命周期。 其实executor.shutdown和shutdownnow也是调用thread.interupte来结束线程池的生命周期的 Java code?// shutdownnow for (Worker w : workers) { w.interruptNow(); } // shutdown for (Worker w : workers) { w.interruptIfIdle(); }
2 其实最简单的方法是设置所创建的thread为守护线程就可以了。 thread factory 生成thread的时候设置t.setDaemon(true);
Java code?// t.setDaemon(true); private static ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, corePoolSize * 2, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(corePoolSize), new ThreadFactory() { public Thread newThread(Runnable r) { // TODO Auto-generated method stub final Thread t = new Thread(r); t.setDaemon(true); threads.add(t); return t; } }, new ThreadPoolExecutor.AbortPolicy());
以下是全部代码
Java code?package test.thread.csdn; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class InterupteThreadTest { private static InterupteThreadTest myThreadPool = null; private static int corePoolSize = 5; private static final List<Thread> threads = new ArrayList<Thread>(); private static ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, corePoolSize * 2, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(corePoolSize), new ThreadFactory() { public Thread newThread(Runnable r) { // TODO Auto-generated method stub final Thread t = new Thread(r); t.setDaemon(true); threads.add(t); return t; } }, new ThreadPoolExecutor.AbortPolicy()); private InterupteThreadTest() { } public static InterupteThreadTest getInstance() { if (null == myThreadPool) { System.out.println("MyThreadPool is creating!"); myThreadPool = new InterupteThreadTest(); } return myThreadPool; } /** * exeWork */ public void exeWork(int availableTime) { FutureTask<Boolean> future = new FutureTask<Boolean>( new Callable<Boolean>() { public Boolean call() { // dead loop mock while (true) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }); executor.execute(future); try { System.out.println(future.get(availableTime, TimeUnit.SECONDS)); } catch (ExecutionException e1) { e1.printStackTrace(); } catch (InterruptedException e2) { e2.printStackTrace(); } catch (TimeoutException e3) { System.out.println("timeout!"); } } public void shut() { executor.shutdown(); } /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { final InterupteThreadTest instance = InterupteThreadTest.getInstance(); instance.exeWork(4); instance.shut(); } }
|