论坛首页 入门技术论坛

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

浏览 29297 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-04-28   最后修改:2009-04-28
在网上查了许久,自己试验了许久,还是不能实现Thread超时自动终止,可能本人对java的知识太浅薄了,希望一起来讨论讨论。

要求:

1.设计一个ReportThread类(继承Thread),实现ReportThread的超时自动终止;
   或者使用线程池:由线程池ThreadPoolExecutor的execute方法运行多个ReportThread,但是其中某一个超出时间MAX_TIME就会自动终止并从线程池中去掉,注意:不光要从线程池中去掉,还要终止该线程。

2.不能用stop interrupt,这两个函数用了等于没用,只是中断一下线程,过一会又会继续运行。
   发表时间: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循环,就是一个个顺序的操作,我不是怕死循环,是要关闭长时间运行的线程
0 请登录后投票
   发表时间: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,这种方法保证了所有的线程都超时了,汗~~
0 请登录后投票
   发表时间: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后引入的这些东西,应该很容易搞定吧
0 请登录后投票
   发表时间: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);
    }
 }


1 请登录后投票
   发表时间:2009-04-28  
A线程中启动B线程执行逻辑
A线程join B线程 超时时interrupt B线程
但是B线程终止需要B线程自己检测interrupt


sun把stop给@Deprecated后 就没提供一种能控制的解决方案

另:谁知道如何提前结束rmi调用
0 请登录后投票
   发表时间: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
……
0 请登录后投票
   发表时间: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的运行时间
0 请登录后投票
   发表时间: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();
        }
    }
0 请登录后投票
   发表时间: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还是运行完成了,没有被终止,这种方式只能通知客户端超时,服务端还是继续运行
0 请登录后投票
论坛首页 入门技术版

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