问题
I have to schedule some tasks at some interval and have to kill the task which is taking more than specified time.
code:
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();
}
}
}
In the above example, i want to kill the task which is taking more than 5 secs(LongTask) without disturbing the execution of other tasks. what is the best way to achieve this?
回答1:
Use ScheduledFuture
to handle it. Try,
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);
For details, look at this docs.
回答2:
After much thought and a lot of search, going with the below approach.
Solution from : 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();
}
}
}
}
来源:https://stackoverflow.com/questions/20279736/java-scheduleexecutorservice-timeout-task