To achieve this behavior you need this :
- Custom class that extends the Thread class and implements the
Runnable interface
- A Thread Executor to simply have asynchronous execution of threads
The Custom class let us named it 'Task' can have a special implemetation as follow :
import java.util.Date;
import java.util.concurrent.Callable;
public class Task implements Callable<String> {
private String name;
private Long elapsedTimeInMillSeconds = 0L;
static int counter = 0;
public Task(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
@Override
public String call() throws Exception {
Long startTimeInNanoSeconds, endTimeInNanoSeconds;
startTimeInNanoSeconds = System.nanoTime();
System.out.println("Executing : " + name + ", Current Seconds : " + new Date().getSeconds());
counter++;
System.out.println("Counter = " + counter + " for thread number " + name);
// Check if our logic is working as expected for Task2 we are going to delay for
// 7 seconds
if (counter == 2)
Thread.sleep(7000);
endTimeInNanoSeconds = System.nanoTime();
elapsedTimeInMillSeconds = (endTimeInNanoSeconds - startTimeInNanoSeconds) / 10000;
System.out
.println("Thread [ name : " + name + ", elapsed time : " + this.elapsedTimeInMillSeconds + " Ms ] ");
return "" + this.elapsedTimeInMillSeconds;
}
public synchronized Long getExecutionTime() {
return elapsedTimeInMillSeconds;
}
}
In your Main class try this :
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class Main {
static final int poolSize = 3;
static int counter = 1;
static final ExecutorService executor = Executors.newFixedThreadPool(poolSize);
public static void main(String[] args) {
List<Callable<Task>> callableTasks = new ArrayList<>();
Callable t1 = new Task("Task1");
Callable t2 = new Task("Task2");
Callable t3 = new Task("Task3");
callableTasks.add(t1);
callableTasks.add(t2);
callableTasks.add(t3);
try {
List<Future<Task>> futures = executor.invokeAll(callableTasks, 3, TimeUnit.SECONDS);
futures.stream().forEach(Ft -> {
Ft.cancel(true);
Task task = null;
try {
task = Ft.get();
} catch (Exception e) {
throw new CancellationException("This Thread has been terminated ");
}
});
executor.shutdownNow();
} catch (Exception e) {
if (e instanceof CancellationException) {
System.out.println("Exception : " + e.getMessage());
}
}
}
}
The Thread where the counter == 2 is going to be terminated, be cause of our delay
future.get()with a timeout - you can call that from a separate thread or thread pool if you need to wait asynchronously. - assylias