我想在一段固定的时间内运行一个线程。如果它没有在那段时间内完成,我想杀死它,抛出一些异常,或以某种方式处理它。怎么办呢?
我从this thread发现的一种方法 是在Thread的run()方法中使用TimerTask。
有没有更好的解决方案?
编辑:添加赏金,因为我需要一个更清晰的答案。下面给出的ExecutorService代码没有解决我的问题。为什么我应该在执行后睡觉()(一些代码 - 我没有处理这段代码)?如果代码完成且sleep()被中断,那怎么可能是timeOut?
需要执行的任务不在我的掌控之中。它可以是任何一段代码。问题是这段代码可能会遇到无限循环。我不希望这种情况发生。所以,我只想在一个单独的线程中运行该任务。父线程必须等到该线程完成并且需要知道任务的状态(即它是否超时或发生了一些异常或者是否成功)。如果任务进入无限循环,我的父线程会无限期地等待,这不是一个理想的情况。
答案 0 :(得分:347)
确实使用ExecutorService
代替Timer
,这里是SSCCE:
package com.stackoverflow.q2275443;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(3, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
future.cancel(true);
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
class Task implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(4000); // Just to demo a long running task of 4 seconds.
return "Ready!";
}
}
使用Future#get()
方法中的timeout
参数稍微玩一下,例如将它增加到5,你会看到线程结束。您可以截取catch (TimeoutException e)
块中的超时。
更新以澄清概念上的误解,sleep()
不是必需的。它仅用于SSCCE /演示目的。只需在sleep()
代替 长期运行的任务即可。在长时间运行的任务中,您应该检查线程是否不是interrupted,如下所示:
while (!Thread.interrupted()) {
// Do your long running task here.
}
答案 1 :(得分:44)
对于任何旧任务,都没有100%可靠的方法来执行此操作。这项任务必须考虑到这种能力。
ExecutorService
等核心Java库在工作线程上使用interrupt()
调用取消异步任务。因此,例如,如果任务包含某种循环,则应在每次迭代时检查其interrupt status。如果任务正在进行I / O操作,那么它们也应该是可中断的 - 并且设置它可能很棘手。无论如何,请记住代码必须主动检查中断;设置中断不一定会做任何事情。
当然,如果你的任务是一个简单的循环,你可以只检查每次迭代的当前时间,并在指定的超时时间结束时放弃。在这种情况下不需要工作线程。
答案 2 :(得分:13)
考虑使用ExecutorService的实例。 invokeAll()
和invokeAny()
方法均可使用timeout
参数。
当前线程将阻塞,直到方法完成(不确定是否需要),因为任务正常完成或达到超时。您可以检查返回的Future
(s)以确定发生了什么。
答案 3 :(得分:8)
更新:为了澄清概念上的误解,不需要sleep()。它仅用于SSCCE /演示目的。只是在那里做长期运行的任务而不是睡觉()。
但是如果用Thread.sleep(4000);
替换for (int i = 0; i < 5E8; i++) {}
,那么它就不会编译,因为空循环不会抛出InterruptedException
。
要使线程可以中断,它需要抛出InterruptedException
。
这对我来说似乎是一个严重的问题。我看不出如何使这个答案适应一般长期运行的任务。
编辑添加:我将此作为一个新问题重新提出:[interrupting a thread after fixed time, does it have to throw InterruptedException?]
答案 4 :(得分:7)
假设线程代码无法控制:
来自上面提到的Java documentation:
如果某个线程没有响应Thread.interrupt怎么办?
在某些情况下,您可以使用特定于应用程序的技巧。例如, 如果线程正在等待已知套接字,则可以关闭套接字 导致线程立即返回。不幸的是,真的 不是任何一般的技术。 应该注意到 等待线程不响应的所有情况 Thread.interrupt,它也不会响应Thread.stop。这样 案例包括故意拒绝服务攻击和I / O操作 thread.stop和thread.interrupt无法正常工作。
底线:
确保所有线程都可以被中断,否则您需要具体的线程知识 - 比如设置一个标志。也许您可以要求将任务与停止它所需的代码一起提供给您 - 使用stop()
方法定义接口。您也可以在未能完成任务时发出警告。
答案 5 :(得分:5)
我认为你应该看一下正确的并发处理机制(运行到无限循环的线程本身听起来不太好,顺便说一句)。请务必仔细阅读"killing" or "stopping" Threads主题。
你所描述的,听起来非常像“约会”,所以你可能想看看CyclicBarrier。
可能有其他构造(例如使用CountDownLatch)可以解决您的问题(一个线程等待锁存器的超时,另一个应该倒计时锁定,如果它完成了它的工作,将在超时或调用锁定倒计时后释放您的第一个线程。
我通常会在此区域推荐两本书:Concurrent Programming in Java和Java Concurrency in Practice。
答案 6 :(得分:5)
我刚刚为此创建了一个帮助类。效果很好:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* TimeOut class - used for stopping a thread that is taking too long
* @author Peter Goransson
*
*/
public class TimeOut {
Thread interrupter;
Thread target;
long timeout;
boolean success;
boolean forceStop;
CyclicBarrier barrier;
/**
*
* @param target The Runnable target to be executed
* @param timeout The time in milliseconds before target will be interrupted or stopped
* @param forceStop If true, will Thread.stop() this target instead of just interrupt()
*/
public TimeOut(Runnable target, long timeout, boolean forceStop) {
this.timeout = timeout;
this.forceStop = forceStop;
this.target = new Thread(target);
this.interrupter = new Thread(new Interrupter());
barrier = new CyclicBarrier(2); // There will always be just 2 threads waiting on this barrier
}
public boolean execute() throws InterruptedException {
// Start target and interrupter
target.start();
interrupter.start();
// Wait for target to finish or be interrupted by interrupter
target.join();
interrupter.interrupt(); // stop the interrupter
try {
barrier.await(); // Need to wait on this barrier to make sure status is set
} catch (BrokenBarrierException e) {
// Something horrible happened, assume we failed
success = false;
}
return success; // status is set in the Interrupter inner class
}
private class Interrupter implements Runnable {
Interrupter() {}
public void run() {
try {
Thread.sleep(timeout); // Wait for timeout period and then kill this target
if (forceStop) {
target.stop(); // Need to use stop instead of interrupt since we're trying to kill this thread
}
else {
target.interrupt(); // Gracefully interrupt the waiting thread
}
System.out.println("done");
success = false;
} catch (InterruptedException e) {
success = true;
}
try {
barrier.await(); // Need to wait on this barrier
} catch (InterruptedException e) {
// If the Child and Interrupter finish at the exact same millisecond we'll get here
// In this weird case assume it failed
success = false;
}
catch (BrokenBarrierException e) {
// Something horrible happened, assume we failed
success = false;
}
}
}
}
它被称为:
long timeout = 10000; // number of milliseconds before timeout
TimeOut t = new TimeOut(new PhotoProcessor(filePath, params), timeout, true);
try {
boolean sucess = t.execute(); // Will return false if this times out
if (!sucess) {
// This thread timed out
}
else {
// This thread ran completely and did not timeout
}
} catch (InterruptedException e) {}
答案 7 :(得分:3)
我给你发了一段代码,说明如何解决问题。 例如,我正在读一个文件。 您可以将此方法用于其他操作,但是您需要实现kill()方法,以便主操作被中断。
希望有所帮助
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* Main class
*
* @author el
*
*/
public class Main {
/**
* Thread which perform the task which should be timed out.
*
* @author el
*
*/
public static class MainThread extends Thread {
/**
* For example reading a file. File to read.
*/
final private File fileToRead;
/**
* InputStream from the file.
*/
final private InputStream myInputStream;
/**
* Thread for timeout.
*/
final private TimeOutThread timeOutThread;
/**
* true if the thread has not ended.
*/
boolean isRunning = true;
/**
* true if all tasks where done.
*/
boolean everythingDone = false;
/**
* if every thing could not be done, an {@link Exception} may have
* Happens.
*/
Throwable endedWithException = null;
/**
* Constructor.
*
* @param file
* @throws FileNotFoundException
*/
MainThread(File file) throws FileNotFoundException {
setDaemon(false);
fileToRead = file;
// open the file stream.
myInputStream = new FileInputStream(fileToRead);
// Instantiate the timeout thread.
timeOutThread = new TimeOutThread(10000, this);
}
/**
* Used by the {@link TimeOutThread}.
*/
public void kill() {
if (isRunning) {
isRunning = false;
if (myInputStream != null) {
try {
// close the stream, it may be the problem.
myInputStream.close();
} catch (IOException e) {
// Not interesting
System.out.println(e.toString());
}
}
synchronized (this) {
notify();
}
}
}
/**
* The task which should be timed out.
*/
@Override
public void run() {
timeOutThread.start();
int bytes = 0;
try {
// do something
while (myInputStream.read() >= 0) {
// may block the thread.
myInputStream.read();
bytes++;
// simulate a slow stream.
synchronized (this) {
wait(10);
}
}
everythingDone = true;
} catch (IOException e) {
endedWithException = e;
} catch (InterruptedException e) {
endedWithException = e;
} finally {
timeOutThread.kill();
System.out.println("-->read " + bytes + " bytes.");
isRunning = false;
synchronized (this) {
notifyAll();
}
}
}
}
/**
* Timeout Thread. Kill the main task if necessary.
*
* @author el
*
*/
public static class TimeOutThread extends Thread {
final long timeout;
final MainThread controlledObj;
TimeOutThread(long timeout, MainThread controlledObj) {
setDaemon(true);
this.timeout = timeout;
this.controlledObj = controlledObj;
}
boolean isRunning = true;
/**
* If we done need the {@link TimeOutThread} thread, we may kill it.
*/
public void kill() {
isRunning = false;
synchronized (this) {
notify();
}
}
/**
*
*/
@Override
public void run() {
long deltaT = 0l;
try {
long start = System.currentTimeMillis();
while (isRunning && deltaT < timeout) {
synchronized (this) {
wait(Math.max(100, timeout - deltaT));
}
deltaT = System.currentTimeMillis() - start;
}
} catch (InterruptedException e) {
// If the thread is interrupted,
// you may not want to kill the main thread,
// but probably yes.
} finally {
isRunning = false;
}
controlledObj.kill();
}
}
/**
* Start the main task and wait for the end.
*
* @param args
* @throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
long start = System.currentTimeMillis();
MainThread main = new MainThread(new File(args[0]));
main.start();
try {
while (main.isRunning) {
synchronized (main) {
main.wait(1000);
}
}
long stop = System.currentTimeMillis();
if (main.everythingDone)
System.out.println("all done in " + (stop - start) + " ms.");
else {
System.out.println("could not do everything in "
+ (stop - start) + " ms.");
if (main.endedWithException != null)
main.endedWithException.printStackTrace();
}
} catch (InterruptedException e) {
System.out.println("You've killed me!");
}
}
}
此致
答案 8 :(得分:2)
我没有看到的一件事是杀死线程通常是一个坏主意。有一些技术可以使线程方法干净地中止,但这与在超时后杀死一个线程不同。
你所建议的风险是你可能不知道杀死它时线程会处于什么状态 - 所以你冒着引入不稳定的风险。更好的解决方案是确保您的线程代码不会自行挂起,或者对中止请求做出很好的响应。
答案 9 :(得分:2)
以下代码段将在单独的线程中启动操作,然后等待最多10秒钟以完成操作。如果操作没有及时完成,代码将尝试取消操作,然后继续其快乐方式。即使操作不能轻易取消,父线程也不会等待子线程终止。
ExecutorService executorService = getExecutorService();
Future<SomeClass> future = executorService.submit(new Callable<SomeClass>() {
public SomeClass call() {
// Perform long-running task, return result. The code should check
// interrupt status regularly, to facilitate cancellation.
}
});
try {
// Real life code should define the timeout as a constant or
// retrieve it from configuration
SomeClass result = future.get(10, TimeUnit.SECONDS);
// Do something with the result
} catch (TimeoutException e) {
future.cancel(true);
// Perform other error handling, e.g. logging, throwing an exception
}
getExecutorService()
方法可以通过多种方式实现。如果您没有任何特殊要求,只需调用Executors.newCachedThreadPool()
进行线程池,线程数没有上限。
答案 10 :(得分:2)
以下是 run 或的 简单易用 帮助类 call 一段Java代码: - )
这是基于answer
中出色的BalusCpackage com.mycompany.util.concurrent;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Calling {@link Callable#call()} or Running {@link Runnable#run()} code
* with a timeout based on {@link Future#get(long, TimeUnit))}
* @author pascaldalfarra
*
*/
public class CallableHelper
{
private CallableHelper()
{
}
public static final void run(final Runnable runnable, int timeoutInSeconds)
{
run(runnable, null, timeoutInSeconds);
}
public static final void run(final Runnable runnable, Runnable timeoutCallback, int timeoutInSeconds)
{
call(new Callable<Void>()
{
@Override
public Void call() throws Exception
{
runnable.run();
return null;
}
}, timeoutCallback, timeoutInSeconds);
}
public static final <T> T call(final Callable<T> callable, int timeoutInSeconds)
{
return call(callable, null, timeoutInSeconds);
}
public static final <T> T call(final Callable<T> callable, Runnable timeoutCallback, int timeoutInSeconds)
{
ExecutorService executor = Executors.newSingleThreadExecutor();
try
{
Future<T> future = executor.submit(callable);
T result = future.get(timeoutInSeconds, TimeUnit.SECONDS);
System.out.println("CallableHelper - Finished!");
return result;
}
catch (TimeoutException e)
{
System.out.println("CallableHelper - TimeoutException!");
if(timeoutCallback != null)
{
timeoutCallback.run();
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (ExecutionException e)
{
e.printStackTrace();
}
finally
{
executor.shutdownNow();
executor = null;
}
return null;
}
}
答案 11 :(得分:2)
BalusC的精彩回答:
但只是添加超时本身不会中断线程本身。即使你在任务中检查while(!Thread.interrupted())。如果你想确保线程被停止,你还应该确保在捕获超时异常时调用future.cancel()。
package com.stackoverflow.q2275443;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(3, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
//Without the below cancel the thread will continue to live
// even though the timeout exception thrown.
future.cancel();
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
class Task implements Callable<String> {
@Override
public String call() throws Exception {
while(!Thread.currentThread.isInterrupted()){
System.out.println("Im still running baby!!");
}
}
}
答案 12 :(得分:0)
我认为答案主要取决于任务本身。
如果第一个答案是肯定而第二个答案是否定的,那么你可以保持简单:
public class Main {
private static final class TimeoutTask extends Thread {
private final long _timeoutMs;
private Runnable _runnable;
private TimeoutTask(long timeoutMs, Runnable runnable) {
_timeoutMs = timeoutMs;
_runnable = runnable;
}
@Override
public void run() {
long start = System.currentTimeMillis();
while (System.currentTimeMillis() < (start + _timeoutMs)) {
_runnable.run();
}
System.out.println("execution took " + (System.currentTimeMillis() - start) +" ms");
}
}
public static void main(String[] args) throws Exception {
new TimeoutTask(2000L, new Runnable() {
@Override
public void run() {
System.out.println("doing something ...");
try {
// pretend it's taking somewhat longer than it really does
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
}
}
如果这不是一个选项,请缩小您的要求 - 或显示一些代码。
答案 13 :(得分:0)
我正在寻找一个ExecutorService,它可以中断由它执行的所有超时Runnables,但没有找到。几个小时后,我创建了一个如下。可以修改此类以增强稳健性。
public class TimedExecutorService extends ThreadPoolExecutor {
long timeout;
public TimedExecutorService(int numThreads, long timeout, TimeUnit unit) {
super(numThreads, numThreads, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(numThreads + 1));
this.timeout = unit.toMillis(timeout);
}
@Override
protected void beforeExecute(Thread thread, Runnable runnable) {
Thread interruptionThread = new Thread(new Runnable() {
@Override
public void run() {
try {
// Wait until timeout and interrupt this thread
Thread.sleep(timeout);
System.out.println("The runnable times out.");
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
interruptionThread.start();
}
}
用法:
public static void main(String[] args) {
Runnable abcdRunnable = new Runnable() {
@Override
public void run() {
System.out.println("abcdRunnable started");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// logger.info("The runnable times out.");
}
System.out.println("abcdRunnable ended");
}
};
Runnable xyzwRunnable = new Runnable() {
@Override
public void run() {
System.out.println("xyzwRunnable started");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// logger.info("The runnable times out.");
}
System.out.println("xyzwRunnable ended");
}
};
int numThreads = 2, timeout = 5;
ExecutorService timedExecutor = new TimedExecutorService(numThreads, timeout, TimeUnit.SECONDS);
timedExecutor.execute(abcdRunnable);
timedExecutor.execute(xyzwRunnable);
timedExecutor.shutdown();
}
答案 14 :(得分:0)
现在,我遇到了这样的问题。它碰巧解码图片。解码过程花费太多时间,屏幕保持黑色。 l添加一个时间控制器:当时间太长,然后从当前线程弹出。 以下是差异:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Bitmap> future = executor.submit(new Callable<Bitmap>() {
@Override
public Bitmap call() throws Exception {
Bitmap bitmap = decodeAndScaleBitmapFromStream(context, inputUri);// do some time consuming operation
return null;
}
});
try {
Bitmap result = future.get(1, TimeUnit.SECONDS);
} catch (TimeoutException e){
future.cancel(true);
}
executor.shutdown();
return (bitmap!= null);
答案 15 :(得分:0)
我遇到了同样的问题。所以我想出了一个像这样的简单解决方案。
public class TimeoutBlock {
private final long timeoutMilliSeconds;
private long timeoutInteval=100;
public TimeoutBlock(long timeoutMilliSeconds){
this.timeoutMilliSeconds=timeoutMilliSeconds;
}
public void addBlock(Runnable runnable) throws Throwable{
long collectIntervals=0;
Thread timeoutWorker=new Thread(runnable);
timeoutWorker.start();
do{
if(collectIntervals>=this.timeoutMilliSeconds){
timeoutWorker.stop();
throw new Exception("<<<<<<<<<<****>>>>>>>>>>> Timeout Block Execution Time Exceeded In "+timeoutMilliSeconds+" Milli Seconds. Thread Block Terminated.");
}
collectIntervals+=timeoutInteval;
Thread.sleep(timeoutInteval);
}while(timeoutWorker.isAlive());
System.out.println("<<<<<<<<<<####>>>>>>>>>>> Timeout Block Executed Within "+collectIntervals+" Milli Seconds.");
}
/**
* @return the timeoutInteval
*/
public long getTimeoutInteval() {
return timeoutInteval;
}
/**
* @param timeoutInteval the timeoutInteval to set
*/
public void setTimeoutInteval(long timeoutInteval) {
this.timeoutInteval = timeoutInteval;
}
}
保证if block在时间限制内没有执行。该过程将终止并抛出异常。
示例:
try {
TimeoutBlock timeoutBlock = new TimeoutBlock(10 * 60 * 1000);//set timeout in milliseconds
Runnable block=new Runnable() {
@Override
public void run() {
//TO DO write block of code
}
};
timeoutBlock.addBlock(block);// execute the runnable block
} catch (Throwable e) {
//catch the exception here . Which is block didn't execute within the time limit
}
答案 16 :(得分:0)
在BalusC给出的解决方案中,主线程将在超时期间保持阻塞状态。如果您的线程池中有多个线程,则将需要与数量相同的其他线程,这些线程将使用Future.get(long timeout,TimeUnit unit)阻塞调用来等待并在超过超时时间时关闭该线程。
此问题的通用解决方案是创建一个可以添加超时功能的ThreadPoolExecutor装饰器。这个Decorator类应该创建与ThreadPoolExecutor一样多的线程,并且所有这些线程应仅用于等待和关闭ThreadPoolExecutor。
通用类应按以下方式实现:
import java.util.List;
import java.util.concurrent.*;
public class TimeoutThreadPoolDecorator extends ThreadPoolExecutor {
private final ThreadPoolExecutor commandThreadpool;
private final long timeout;
private final TimeUnit unit;
public TimeoutThreadPoolDecorator(ThreadPoolExecutor threadpool,
long timeout,
TimeUnit unit ){
super( threadpool.getCorePoolSize(),
threadpool.getMaximumPoolSize(),
threadpool.getKeepAliveTime(TimeUnit.MILLISECONDS),
TimeUnit.MILLISECONDS,
threadpool.getQueue());
this.commandThreadpool = threadpool;
this.timeout=timeout;
this.unit=unit;
}
@Override
public void execute(Runnable command) {
super.execute(() -> {
Future<?> future = commandThreadpool.submit(command);
try {
future.get(timeout, unit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException | TimeoutException e) {
throw new RejectedExecutionException(e);
} finally {
future.cancel(true);
}
});
}
@Override
public void setCorePoolSize(int corePoolSize) {
super.setCorePoolSize(corePoolSize);
commandThreadpool.setCorePoolSize(corePoolSize);
}
@Override
public void setThreadFactory(ThreadFactory threadFactory) {
super.setThreadFactory(threadFactory);
commandThreadpool.setThreadFactory(threadFactory);
}
@Override
public void setMaximumPoolSize(int maximumPoolSize) {
super.setMaximumPoolSize(maximumPoolSize);
commandThreadpool.setMaximumPoolSize(maximumPoolSize);
}
@Override
public void setKeepAliveTime(long time, TimeUnit unit) {
super.setKeepAliveTime(time, unit);
commandThreadpool.setKeepAliveTime(time, unit);
}
@Override
public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
super.setRejectedExecutionHandler(handler);
commandThreadpool.setRejectedExecutionHandler(handler);
}
@Override
public List<Runnable> shutdownNow() {
List<Runnable> taskList = super.shutdownNow();
taskList.addAll(commandThreadpool.shutdownNow());
return taskList;
}
@Override
public void shutdown() {
super.shutdown();
commandThreadpool.shutdown();
}
}
上述装饰器可以按以下方式使用:
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args){
long timeout = 2000;
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(3, 10, 0, TimeUnit.MILLISECONDS, new SynchronousQueue<>(true));
threadPool = new TimeoutThreadPoolDecorator( threadPool ,
timeout,
TimeUnit.MILLISECONDS);
threadPool.execute(command(1000));
threadPool.execute(command(1500));
threadPool.execute(command(2100));
threadPool.execute(command(2001));
while(threadPool.getActiveCount()>0);
threadPool.shutdown();
}
private static Runnable command(int i) {
return () -> {
System.out.println("Running Thread:"+Thread.currentThread().getName());
System.out.println("Starting command with sleep:"+i);
try {
Thread.sleep(i);
} catch (InterruptedException e) {
System.out.println("Thread "+Thread.currentThread().getName()+" with sleep of "+i+" is Interrupted!!!");
return;
}
System.out.println("Completing Thread "+Thread.currentThread().getName()+" after sleep of "+i);
};
}
}