2013-11-29 36 views
1

我必須在某個時間間隔安排一些任務,並且必須殺死超過指定時間的任務。java ScheduleExecutorService超時任務

代碼:

public class ExecutorMain { 
    public static void main(String[] args) throws InterruptedException, ExecutionException,  TimeoutException { 
    ScheduledThreadPoolExecutor scheduledExecutorService = new  ScheduledThreadPoolExecutor(2); 
    scheduledExecutorService.scheduleAtFixedRate(new ShortTask(2), 0, 3, TimeUnit.SECONDS); 
    scheduledExecutorService.scheduleAtFixedRate(new LongTask(1), 0, 10, TimeUnit.SECONDS); 
    } 
} 

class ShortTask implements Runnable { 
    private int id; 
    ShortTask(int id) { 
    this.id = id; 
    } 
    public void run() { 
    try { 
     Thread.sleep(1000); 
     System.out.println("Short Task with id "+id+" executed by "+Thread.currentThread().getId()); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    } 
} 

class LongTask implements Runnable { 
    private int id; 
    LongTask(int id) { 
    this.id = id; 
    } 
    public void run() { 
    try { 
     Thread.sleep(6000); 
     System.out.println("Long Task with id "+id+" executed by "+Thread.currentThread().getId()); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    } 
} 

在上述例子中,我要殺死它,而不會干擾其他任務的執行時超過5秒(LongTask)的任務。達到這個目標的最好方法是什麼?

回答

0

經過多方面的考慮和大量的搜索,使用下面的方法。

解決方案來源:https://stackoverflow.com/a/808367/3048186

public class ExecutorMain { 
    public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException { 
     ScheduledThreadPoolExecutor scheduledExecutorService = new ScheduledThreadPoolExecutor(2); 
     scheduledExecutorService.scheduleAtFixedRate(new ShortTask(1, 5000), 0, 3, TimeUnit.SECONDS); 
     scheduledExecutorService.scheduleAtFixedRate(new ShortTask(2, 5000), 0, 3, TimeUnit.SECONDS); 
     scheduledExecutorService.scheduleAtFixedRate(new LongTask(1, 5000), 0, 10, TimeUnit.SECONDS); 
     scheduledExecutorService.scheduleAtFixedRate(new LongTask(2, 5000), 0, 10, TimeUnit.SECONDS); 
    } 
} 

class Worker extends Thread { 
    private final Process process; 
    private Integer exit; 
    String id; 
    Worker(Process process, String id) { 
    this.process = process; 
    this.id = id; 
    } 
    public void run() { 
    try { 
     exit = process.waitFor(); 
    } catch (InterruptedException ignore) { 
     //NOOP 
    } 
} 

public Integer getExit() { 
    return exit; 
    } 
} 

class ShortTask implements Runnable { 
    private int id; 
    private long timeOut; 
    ShortTask(int id, long timeOut) { 
    this.id = id; 
    this.timeOut = timeOut; 
    } 
    public void run() { 

    long start = System.currentTimeMillis(); 

    Runtime runtime = Runtime.getRuntime(); 
    Process process = null; 
    try { 
     process = runtime.exec("sleep 1s"); 
    } catch (IOException e) { 
     System.out.println("ShortTask IOE"); 
    } 
    Worker worker = new Worker(process, "short task"+id); 
    worker.start(); 
    try { 
     worker.join(timeOut); 
     long total = System.currentTimeMillis()-start; 
     //If time out, exit code would be null 
     System.out.println(" Short task id :"+id+" Exit Code : " +worker.getExit()+" thread id "+Thread.currentThread().getId()+" in time "+total); 
    } catch(InterruptedException ex) { 
     worker.interrupt(); 
     Thread.currentThread().interrupt(); 
    } finally { 
     if(process != null) { 
      process.destroy(); 
     } 
    } 
} 
} 

class LongTask implements Runnable { 
    private int id; 
    private long timeOut; 
    LongTask(int id, long timeOut) { 
    this.id = id; 
    this.timeOut = timeOut; 
    } 
    public void run() { 

    long start = System.currentTimeMillis(); 

    Runtime runtime = Runtime.getRuntime(); 
    Process process = null; 
    try { 
     process = runtime.exec("sleep 60s"); 
    } catch (IOException e) { 
     System.out.println("LongTask IOE"); 
    } 
    Worker worker = new Worker(process, "long task"+id); 
    worker.start(); 
    try { 
     worker.join(timeOut); 
     long total = System.currentTimeMillis() - start; 
     //If time out, exit code would be null 
     System.out.println(" Long Task id :"+id+" Exit Code : " +worker.getExit()+" thread id "+Thread.currentThread().getId()+" in time "+total); 
    } catch(InterruptedException ex) { 
     worker.interrupt(); 
     Thread.currentThread().interrupt(); 
    } finally { 
     if(process != null) { 
      process.destroy(); 
     } 
    } 
    } 
} 
0

使用ScheduledFuture來處理它。嘗試,

final ScheduledFuture<?> longTaskHandler= 
      scheduledExecutorService.scheduleAtFixedRate(new LongTask(1), 
      0, 10, TimeUnit.SECONDS); 

scheduledExecutorService.schedule(new Runnable() { 
     public void run() { 
      longTaskHandler.cancel(true); 
     // This will cancel your LongTask after 5 sec without effecting ShortTask 
     } 
    }, 5, TimeUnit.SECONDS); 

有關詳細信息,看看這個docs

+0

我想到了這一點,但如果我有這些都佔用比超時時間來執行更多的多項任務,然後我給大家分享我的線程這個取消任務。如果任務知道其超時,那麼我們不必安排線程來檢查超時。 –

+0

@SatishM,這隻會影響你的LongTask,ShortTask會繼續工作。 – Masudul

+0

上面的例子是採取2個任務,但實際上我有多個任務,所以我必須安排這個取消任務的所有主要任務(我不知道哪個任務將需要更多的時間比超時實際)。 –