锁定老帖子 主题:不可能完成任务?Thread的超时自动终止
精华帖 (0) :: 良好帖 (2) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-28
最后修改:2009-04-28
要求: 1.设计一个ReportThread类(继承Thread),实现ReportThread的超时自动终止; 或者使用线程池:由线程池ThreadPoolExecutor的execute方法运行多个ReportThread,但是其中某一个超出时间MAX_TIME就会自动终止并从线程池中去掉,注意:不光要从线程池中去掉,还要终止该线程。 2.不能用stop interrupt,这两个函数用了等于没用,只是中断一下线程,过一会又会继续运行。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-04-28
最后修改:2009-04-28
不行的方法一:
package thread; public class ThreadTimeout extends Thread { public long startTimeMillis = 0; public volatile boolean finished = false; Thread thread; public ThreadTimeout() { this.startTimeMillis = System.currentTimeMillis(); System.out.println("startTimeMillis" + startTimeMillis); start(); } public static void main(String args[]) { ThreadTimeout a = new ThreadTimeout(); a.doWork(); } public void run() { while (!finished) { timeout(); } } private void doWork() { int i = 0; while(true){ if (finished) { System.out.println("time out"); break; } System.out.println(i++); } } private boolean timeout() { long accessTime = System.currentTimeMillis() - startTimeMillis; while (accessTime < 600) { System.out.println("accessTime " + accessTime); return true; } finished = true; return false; } } !!不行,我的doWork里边没有while循环,就是一个个顺序的操作,我不是怕死循环,是要关闭长时间运行的线程 |
|
返回顶楼 | |
发表时间:2009-04-28
最后修改:2009-04-28
不行的方法二:
package thread; import java.util.Random; import java.util.Timer; import java.util.TimerTask; public class ThreadA extends Thread { private static final int MAX_TIME = 80; private boolean running = true; public ThreadA(String name) { super(name); Timer timer = new Timer(); EndThreadTask task = new EndThreadTask(this); timer.schedule(task, MAX_TIME); } public void run() { try { this.sleep(1000); //业务逻辑 } catch (InterruptedException e) { System.out.println("错误终止"); } } public void doWorks(){ long startTime = System.currentTimeMillis(); Random rand = new Random(System.nanoTime()); int delay = rand.nextInt(100); while(true){ System.out.println("我还在运行呢"); } } public void stopRunning(){ this.running = false; } public static void main(String args[]){ ThreadA a = new ThreadA("a"); a.start(); } } class EndThreadTask extends TimerTask{ private ThreadA thread; public EndThreadTask(ThreadA thread){ this.thread = thread; } public void run() { System.out.println(this.thread.getName()+"超时"); this.thread.interrupt(); } } !!不行,我怎么可能在我运行业务逻辑时调用sleep,这种方法保证了所有的线程都超时了,汗~~ |
|
返回顶楼 | |
发表时间:2009-04-28
最后修改:2009-04-28
ScheduledExecutorService scheduledExecutorService=Executors.newScheduledThreadPool(5); ScheduledFuture<?> future =scheduledExecutorService.scheduleAtFixedRate(new Runnable(){ @Override public void run() { //do something } }, 1,8, TimeUnit.MINUTES) ; future.cancel() 用1.5后引入的这些东西,应该很容易搞定吧 |
|
返回顶楼 | |
发表时间:2009-04-28
import static java.util.concurrent.TimeUnit.*; class BeeperControl { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public void beepForAnHour() { final Runnable beeper = new Runnable() { public void run() { System.out.println("beep"); } }; final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS); scheduler.schedule(new Runnable() { public void run() { beeperHandle.cancel(true); } }, 60 * 60, SECONDS); } } |
|
返回顶楼 | |
发表时间:2009-04-28
A线程中启动B线程执行逻辑
A线程join B线程 超时时interrupt B线程 但是B线程终止需要B线程自己检测interrupt sun把stop给@Deprecated后 就没提供一种能控制的解决方案 另:谁知道如何提前结束rmi调用 |
|
返回顶楼 | |
发表时间:2009-04-28
vvggsky 写道 import static java.util.concurrent.TimeUnit.*; class BeeperControl { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public void beepForAnHour() { final Runnable beeper = new Runnable() { public void run() { System.out.println("beep"); } }; final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS); scheduler.schedule(new Runnable() { public void run() { beeperHandle.cancel(true); } }, 60 * 60, SECONDS); } } 不行呢?为了省时,我把TimeUnit变成了MILLISECONDS import java.util.concurrent.*; public class BeeperControl { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public void beepForAnHour() { final Runnable beeper = new Runnable() { public void run() { //业务 while(true) System.out.println("do my task"); } }; final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper, 10, 10, TimeUnit.MILLISECONDS); scheduler.schedule(new Runnable() { public void run() { beeperHandle.cancel(true); System.out.println("task canceled"); } }, 60 * 60, TimeUnit.MILLISECONDS); } public static void main(String args[]){ BeeperControl b = new BeeperControl(); b.beepForAnHour(); } } 结果输出是 do my task do my task do my task do my task …… |
|
返回顶楼 | |
发表时间:2009-04-28
yishh 写道 ScheduledExecutorService scheduledExecutorService=Executors.newScheduledThreadPool(5); ScheduledFuture<?> future =scheduledExecutorService.scheduleAtFixedRate(new Runnable(){ @Override public void run() { //do something } }, 1,8, TimeUnit.MINUTES) ; future.cancel() 用1.5后引入的这些东西,应该很容易搞定吧 怎么计算运行时间呢,我需要在Thread run的时候才开始计时,因为要限制Thread的运行时间 |
|
返回顶楼 | |
发表时间:2009-04-28
看看 Http-Client 中怎么处理的吧,对于兼容1.4中建立Socket超时问题的解决方案:
/** * Executes <code>task</code>. Waits for <code>timeout</code> * milliseconds for the task to end and returns. If the task does not return * in time, the thread is interrupted and an Exception is thrown. * The caller should override the Thread.interrupt() method to something that * quickly makes the thread die or use Thread.isInterrupted(). * @param task The thread to execute * @param timeout The timeout in milliseconds. 0 means to wait forever. * @throws TimeoutException if the timeout passes and the thread does not return. */ public static void execute(Thread task, long timeout) throws TimeoutException { task.start(); try { task.join(timeout); } catch (InterruptedException e) { /* if somebody interrupts us he knows what he is doing */ } if (task.isAlive()) { task.interrupt(); throw new TimeoutException(); } } |
|
返回顶楼 | |
发表时间:2009-04-28
最后修改:2009-04-28
ispring 写道 看看 Http-Client 中怎么处理的吧,对于兼容1.4中建立Socket超时问题的解决方案:
/** * Executes <code>task</code>. Waits for <code>timeout</code> * milliseconds for the task to end and returns. If the task does not return * in time, the thread is interrupted and an Exception is thrown. * The caller should override the Thread.interrupt() method to something that * quickly makes the thread die or use Thread.isInterrupted(). * @param task The thread to execute * @param timeout The timeout in milliseconds. 0 means to wait forever. * @throws TimeoutException if the timeout passes and the thread does not return. */ public static void execute(Thread task, long timeout) throws TimeoutException { task.start(); try { task.join(timeout); } catch (InterruptedException e) { /* if somebody interrupts us he knows what he is doing */ } if (task.isAlive()) { task.interrupt(); throw new TimeoutException(); } } 我写了一个ThreadA,用以上方法运行结果还是不行 public class ThreadA extends Thread { private long startTime; public ThreadA(String name) { super(name); } public void run() { this.startTime = System.currentTimeMillis(); int i = 0; while (i++<20) { try { this.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.getName()+":"+i); } System.out.println(this.getName()+"已完成"); } } 结果: java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at thread.ThreadA.run(ThreadA.java:22) Exception in thread "main" java.util.concurrent.TimeoutException at thread.Test.execute(Test.java:28) a:1 at thread.Test.main(Test.java:16) a:2 a:3 a:4 a:5 a:6 a:7 a:8 a:9 a:10 a:11 a:12 a:13 a:14 a:15 a:16 a:17 a:18 a:19 a:20 a已完成 说明Thread还是运行完成了,没有被终止,这种方式只能通知客户端超时,服务端还是继续运行 |
|
返回顶楼 | |