论坛首页 入门技术论坛

不可能完成任务?Thread的超时自动终止

浏览 29292 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-05-05  
C_J 写道
 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();   
        }   
    }  



这种办法不能满足楼主的需求么?(不能完全保证时间的精确)

看到楼主实验了,运行不成功吗?


join是等待线程结束,timeout设置等待时间,如果超时,则线程进入调度。查了下JDK对wait(long)的注释是:

引用

The specified amount of real time has elapsed, more or less.The thread <var>T</var> is then removed from the wait set for this
object and re-enabled for thread scheduling.


interrupt();官方有这样一段解释:

引用
* <p> Unless the current thread is interrupting itself, which is
     * always permitted, the {@link #checkAccess() checkAccess} method
     * of this thread is invoked, which may cause a {@link
     * SecurityException} to be thrown.


弱弱的问句“影子线程”不用interrupt()吗?

希望对楼主有所帮助!

这个我上边有例子试验过了,不行
0 请登录后投票
   发表时间:2009-05-05  
为什么?

if (task.isAlive()) {     
           task.interrupt();     
           throw new TimeoutException();     
       }    

isAlive不进去么?
0 请登录后投票
   发表时间:2009-05-05  
看具体情况吧,可以考虑用stop
0 请登录后投票
   发表时间:2009-05-09  
这种情况,更适合使用进程而不是线程。
0 请登录后投票
   发表时间:2009-05-09   最后修改:2009-05-09
	public static void main(String[] args) {
		timeout(5);
	}

	public static void timeout(long time) {
		ExecutorService executor = Executors.newSingleThreadExecutor();
		Future<String> future = executor.submit(new Callable<String>() {

			@Override
			public String call() throws Exception {
				Thread.sleep(10000);
				return null;
			}
		});

		try {
			future.get(time, TimeUnit.MILLISECONDS);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
0 请登录后投票
   发表时间:2009-05-11   最后修改:2009-05-11
public static void main(String[] args) {
		final ScheduledExecutorService scheduler = Executors
				.newScheduledThreadPool(2);
		final Runnable beeper = new Runnable() {
			int count = 0;

			public void run() {
				System.out.println(new Date() + " beep " + (++count));
			}
		};
		// 1秒钟后运行,并每隔2秒运行一次
		final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
				beeper, 1, 2, TimeUnit.SECONDS);
		// 2秒钟后运行,并每次在上次任务运行完后等待5秒后重新运行
		final ScheduledFuture<?> beeperHandle2 = scheduler
				.scheduleWithFixedDelay(beeper, 2, 5, TimeUnit.SECONDS);
		// 30秒后结束关闭任务,并且关闭Scheduler
		scheduler.schedule(new Runnable() {
			public void run() {
				beeperHandle.cancel(true);
				beeperHandle2.cancel(true);
				scheduler.shutdown();
			}
		}, 30, TimeUnit.SECONDS);
	}
0 请登录后投票
   发表时间:2009-05-11  
kowen 写道
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
……


把其中beeper 方法中的while (true)去掉即可
0 请登录后投票
   发表时间:2009-05-11  
利用ScheduledThreadPoolExecutor来执行runnable,得到future后调get(long timeout, TimeUnit unit) 就可以了
0 请登录后投票
   发表时间:2009-05-12  
mesmes 写道
kowen 写道
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
……


把其中beeper 方法中的while (true)去掉即可

设置while(true)是为了超时啊,不用while(true)当然可以了,瞬间就执行完了
0 请登录后投票
   发表时间:2009-05-13  
还在讨论呢,还是那句话,不可能,除非把大的任务分解为很小的任务,然后用标量来判断。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics