I have 2 tasks - Task A and Task B. Task A should execute first and on completion, I want to start my periodic Task B which keeps doing a task until it becomes success.
How can I implement this in java? I was looking at scheduled execution services but those seem to be more time based rather than state of a task.
Here's one way:
import java.util.concurrent.*;
public class ScheduledTasks {
public static void main(String[] args) {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
FollowupTask followupTask = new FollowupTask(executorService);
FirstTask firstTask = new FirstTask(followupTask, executorService);
executorService.submit(firstTask);
}
static class FirstTask implements Runnable {
private FollowupTask followup;
private ScheduledExecutorService executorService;
FirstTask(FollowupTask followup, ScheduledExecutorService executorService) {
this.followup = followup;
this.executorService = executorService;
}
#Override
public void run() {
System.out.println("First task: counting to 5");
for (int i = 1; i <= 5; i++) {
sleep(1000);
System.out.println(i);
}
System.out.println("All done! Submitting followup task.");
executorService.submit(followup);
}
}
static class FollowupTask implements Runnable {
private int invocationCount = 0;
private ScheduledExecutorService executorService;
public FollowupTask(ScheduledExecutorService executorService) {
this.executorService = executorService;
}
#Override
public void run() {
invocationCount++;
if (invocationCount == 1) {
System.out.println("Followup task: resubmit while invocationCount < 20");
}
System.out.println("invocationCount = " + invocationCount);
if (invocationCount < 20) {
executorService.schedule(this, 250, TimeUnit.MILLISECONDS);
} else {
executorService.shutdown();
}
}
}
static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new IllegalStateException("I shouldn't be interrupted!", e);
}
}
}
Related
I have a bunch of worker threads that I want to execute sequentially after a giving delay. I would like to achieve the following behaviour:
DELAY -> Worker 1 -> DELAY -> Worker 2 - DELAY -> Worker 3 -> ...
I came up with this solution:
long delay = 5;
for(String value : values) {
WorkerThread workerThread = new WorkerThread(value);
executorService.schedule(workerThread, delay, TimeUnit.SECONDS);
delay = delay + 5;
}
where executorService has been created like:
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
Is there any other way to achieve this with ExecutorService in Java?
Looking at your problem, I came up with another solution. Assuming values is a queue which can be changed. Here is a solution which works. I modified your WorkerThread a little and added a callback object in there. Hope this helps.
private final Queue<String> values = new LinkedList<>();
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private void start() {
AtomicLong delay = new AtomicLong(5);
String value = values.poll();
if (value != null) {
WorkerThread workerThread = new WorkerThread(value, new OnCompleteCallback() {
#Override
public void complete() {
String valueToProcessNext = values.poll();
if (valueToProcessNext != null) {
executorService.schedule(new WorkerThread(valueToProcessNext, this), delay.addAndGet(5), TimeUnit.SECONDS);
}
}
});
executorService.schedule(workerThread, delay.get(), TimeUnit.SECONDS);
}
}
class WorkerThread implements Runnable {
private final String value;
private final OnCompleteCallback callback;
WorkerThread(String value, OnCompleteCallback callback) {
this.value = value;
this.callback = callback;
}
#Override
public void run() {
try {
System.out.println(value);
} finally {
callback.complete();
}
}
}
interface OnCompleteCallback {
void complete();
}
Nothing comes to mind except for your solution if ExecutorService should be used. However you will probably find CompletableFuture more useful cause it provides similar behavior but with delay relative to task completion instead for start of scheduling.
CompletableFuture<Void> completableFuture = CompletableFuture.completedFuture(null);
String[] values = new String[]{"a", "b", "c"};
for (String value : values) {
completableFuture
.thenRun(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
})
.thenRun(() -> System.out.println(value));
}
completableFuture.get();
You can use a DelayQueue between each worker. And decorate your workers with this class :
public class DelayedTask implements Runnable {
private final Runnable task;
private final DelayQueue<Delayed> waitQueue;
private final DelayQueue<Delayed> followerQueue;
public DelayedTask(Runnable task, DelayQueue<Delayed> waitQueue, DelayQueue<Delayed> followerQueue) {
this.task = Objects.requireNonNull(task);
this.waitQueue = Objects.requireNonNull(waitQueue);
this.followerQueue = followerQueue;
}
#Override
public void run() {
try {
waitQueue.take();
try {
task.run();
} finally {
if (followerQueue != null) {
followerQueue.add(new Delay(3, TimeUnit.SECONDS));
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
and a simple Delayed implementation
class Delay implements Delayed {
private final long nanos;
Delay(long amount, TimeUnit unit) {
this.nanos = TimeUnit.NANOSECONDS.convert(amount, unit) + System.nanoTime();
}
#Override
public long getDelay(TimeUnit unit) {
return unit.convert(nanos - System.nanoTime(), TimeUnit.NANOSECONDS);
}
#Override
public int compareTo(Delayed other) {
return Long.compare(nanos, other.getDelay(TimeUnit.NANOSECONDS));
}
}
Allowing for this usage :
ExecutorService executorService = Executors.newFixedThreadPool(1);
// ....
DelayQueue<Delayed> currentQueue = new DelayQueue<>();
currentQueue.add(new Delay(3, TimeUnit.SECONDS));
for (String value : values) {
DelayedTask delayedTask = new DelayedTask(new WorkerThread(value), currentQueue, currentQueue = new DelayQueue<>());
executorService.submit(delayedTask);
}
I have a situation where i need to check if a certain condition is met and it needs to be periodically executed a certain number of times to check for the condition before it declares the condition as not met and between each execution there needs to be a delay/sleep interval.
Code Structure:
class checkCondition<T> implements Callable<T>{
#Override
public T call() {
//Do Stuff and return result
return result;
}
public class TaskRunner<T> {
private final ExecutorService executor = Executors.newSingleThreadExecutor();
public Future<T> runTask(checkCondiiton task, int times, long sleep){
while(times > 0){
future = executor.submit(task);
Thread.sleep(sleep);
times--;
}
return future;
}
}
}
Is the above implementation correct? If not, please advice on what would be better approach. I am new to ExecutorService and Java Concurrency.
Try using Executors.newSingleThreadScheduledExecutor()
Example:
public class FixedScheduledExcutor
{
public static void main(String[] args) throws InterruptedException
{
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
CountDownLatch latch = new CountDownLatch(5);
executorService.scheduleAtFixedRate(new MyRunner(latch), 5, 5, TimeUnit.SECONDS);
latch.await();
System.out.println("Shutting down service...");
executorService.shutdown();
}
}
class MyRunner implements Runnable
{
CountDownLatch latch;
MyRunner(CountDownLatch latch)
{
this.latch = latch;
}
#Override
public void run()
{
System.out.println("Do something : " + latch.getCount());
latch.countDown();
}
}
I would like to get all counts from WorkerThread class after the 5 threads finished. Does the Counter work the way as expected? Thanks. In the WorkerThread constructor, it seems each counter becomes one variable of each thread, not shared among the 5 threads.
public class Test {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
Counter counter = new Counter();
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread(String.valueOf(i), counter);
executor.execute(worker);
}
executor.shutdown();
System.out.println("Total Count: " + counter.value());
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
}
}
class Counter{
private AtomicInteger count;
public Counter(){
count = new AtomicInteger();
}
public int increment(){
return count.incrementAndGet();
}
public int value(){
return count.get();
}
}
class WorkerThread implements Runnable {
private String command;
private Counter c;
public WorkerThread(String s, Counter c){
this.command=s;
this.c = c;
}
#Override
public void run() {
for(int i=0; i<6; i++){
c.increment();
}
processCommand();
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public String toString(){
return this.command;
}
}
Synchronization seems correct to me. If counting is your only task, you could skip the Counter class and directly use AtomicInteger to remove complexity. (Keep it if you want to realize more complex tasks which require a proper synchronized shared state object).
Don't call your worker class "Thread". It is not a thread, it is a task that is executed by a thread.
Last but not least, there's something wrong with your shutdown-code. Note that shutdown does not block but return immediately. So you're evaluating your counter too early.
The following code fixes all of this issues:
public class Test {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
AtomicInteger counter = new AtomicInteger();
for (int i = 0; i < 10; i++) {
executor.execute(new Worker(counter));
}
executor.shutdown();
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
// executor does not shut down.
// try executor.shutdownNow() etc.
}
System.out.println("Total Count: " + counter.get());
}
}
class Worker implements Runnable {
private final AtomicInteger counter;
public Worker(AtomicInteger counter) {
this.counter = counter;
}
public void run() {
// do something
counter.incrementAndGet();
// do something else
}
}
For more information about how to correctly shutdown an ExecutorService, see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html, section 'Usage Examples'.
I have a ScheduledThreadPoolExecutor with which I schedule a task to run at a fixed rate. I want the task to be running with a specified delay for a maximum of say 10 times until it "succeeds". After that, I will not want the task to be retried. So basically I'll need to stop running the scheduled task when I want it to be stopped, but without shutting down the ScheduledThreadPoolExecutor. Any idea how I'd do that?
Here's some pseudocode -
public class ScheduledThreadPoolExecutorTest
{
public static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(15); // no multiple instances, just one to serve all requests
class MyTask implements Runnable
{
private int MAX_ATTEMPTS = 10;
public void run()
{
if(++attempt <= MAX_ATTEMPTS)
{
doX();
if(doXSucceeded)
{
//stop retrying the task anymore
}
}
else
{
//couldn't succeed in MAX attempts, don't bother retrying anymore!
}
}
}
public void main(String[] args)
{
executor.scheduleAtFixedRate(new ScheduledThreadPoolExecutorTest().new MyTask(), 0, 5, TimeUnit.SECONDS);
}
}
run this test, it prints 1 2 3 4 5 and stops
public class ScheduledThreadPoolExecutorTest {
static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(15); // no
static ScheduledFuture<?> t;
static class MyTask implements Runnable {
private int attempt = 1;
public void run() {
System.out.print(attempt + " ");
if (++attempt > 5) {
t.cancel(false);
}
}
}
public static void main(String[] args) {
t = executor.scheduleAtFixedRate(new MyTask(), 0, 1, TimeUnit.SECONDS);
}
}
Nicely cancelled outside of thread:
public class ScheduleTest {
#Test
public void testCancel() throws Exception {
final ScheduledThreadPoolExecutor EXECUTOR = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(2);
ScheduledFuture f1 = EXECUTOR.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
System.out.println("Im alive 1");
}
}, 0, 1, TimeUnit.SECONDS);
ScheduledFuture f2 = EXECUTOR.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
System.out.println("Im alive 2");
}
}, 0, 2, TimeUnit.SECONDS);
Thread.sleep(10000);
f1.cancel(true);
System.out.println("f1 cancel");
Thread.sleep(10000);
f2.cancel(false);
System.out.println("f2 cancel");
Thread.sleep(10000);
}
}
Sometimes thread couldn't be cancelled, this solved usually via volatile boolean isCancelled;
CountDownLatch is an alternative approach. When the thread completes, call countDown() on the latch. The calling thread calls latch.await() until all threads complete. At that point call ExecutorService.shutdownNow() so that your main thread doesn't turn into a zombie.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolExecutorTest {
static int i = 0;
public static void main(String[] args) throws Exception {
final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
final CountDownLatch latch = new CountDownLatch(1);
executor.scheduleAtFixedRate(() -> {
System.out.println(++i);
if (i > 4) {
latch.countDown();
}
}, 0, 100, TimeUnit.MILLISECONDS);
latch.await();
executor.shutdownNow();
}
}
How can i order threads in the order they were instantiated.e.g. how can i make the below program print the numbers 1...10 in order.
public class ThreadOrdering {
public static void main(String[] args) {
class MyRunnable implements Runnable{
private final int threadnumber;
MyRunnable(int threadnumber){
this.threadnumber = threadnumber;
}
public void run() {
System.out.println(threadnumber);
}
}
for(int i=1; i<=10; i++){
new Thread(new MyRunnable(i)).start();
}
}
}
Sounds like you want ExecutorService.invokeAll, which will return results from worker threads in a fixed order, even though they may be scheduled in arbitrary order:
import java.util.ArrayList;
import java.util.List;
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;
public class ThreadOrdering {
static int NUM_THREADS = 10;
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS);
class MyCallable implements Callable<Integer> {
private final int threadnumber;
MyCallable(int threadnumber){
this.threadnumber = threadnumber;
}
public Integer call() {
System.out.println("Running thread #" + threadnumber);
return threadnumber;
}
}
List<Callable<Integer>> callables =
new ArrayList<Callable<Integer>>();
for(int i=1; i<=NUM_THREADS; i++) {
callables.add(new MyCallable(i));
}
try {
List<Future<Integer>> results =
exec.invokeAll(callables);
for(Future<Integer> result: results) {
System.out.println("Got result of thread #" + result.get());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
} finally {
exec.shutdownNow();
}
}
}
"I actually have some parts that i want to execute in parallel, and then once the results are generated, I want to merge the results in certain order." Thanks, this clarifies what you're asking.
You can run them all at once, but the important thing is to get their results in order when the threads finish their computation. Either Thread#join() them in the order in which you want to get their results, or just Thread#join() them all and then iterate through them to get their results.
// Joins the threads back to the main thread in the order we want their results.
public class ThreadOrdering {
private class MyWorker extends Thread {
final int input;
int result;
MyWorker(final int input) {
this.input = input;
}
#Override
public void run() {
this.result = input; // Or some other computation.
}
int getResult() { return result; }
}
public static void main(String[] args) throws InterruptedException {
MyWorker[] workers = new MyWorker[10];
for(int i=1; i<=10; i++) {
workers[i] = new MyWorker(i);
workers[i].start();
}
// Assume it may take a while to do the real computation in the threads.
for (MyWorker worker : workers) {
// This can throw InterruptedException, but we're just passing that.
worker.join();
System.out.println(worker.getResult());
}
}
}
Simply put, the scheduling of threads is indeterminate.
http://www.janeg.ca/scjp/threads/scheduling.html Dead domain - do not click
WaybackMachine version of the above page
The longer answer is that if you want to do this, you'll need to manually wait for each thread to complete its work before you allow another to run. Note that in this fashion, all the threads will still interleave but they won't accomplish any work until you give the go-ahead. Have a look at the synchronize reserved word.
You can chain them – that is, have the first one start the second, the second start the third, etc. They won't really be running at the same time except for a bit of overlap when each one is started.
public class ThreadOrdering
{
public static void main(String[] args)
{
MyRunnable[] threads = new MyRunnable[10];//index 0 represents thread 1;
for(int i=1; i<=10; i++)
threads[i] = new MyRunnable(i, threads);
new Thread(threads[0].start);
}
}
public class MyRunnable extends Runnable
{
int threadNumber;
MyRunnable[] threads;
public MyRunnable(int threadNumber, MyRunnable[] threads)
{
this.threadnumber = threadnumber;
this.threads = threads;
}
public void run()
{
System.out.println(threadnumber);
if(threadnumber!=10)
new Thread(threadnumber).start();
}
}
Here's a way to do it without having a master thread that waits for each result. Instead, have the worker threads share an object which orders the results.
import java.util.*;
public class OrderThreads {
public static void main(String... args) {
Results results = new Results();
new Thread(new Task(0, "red", results)).start();
new Thread(new Task(1, "orange", results)).start();
new Thread(new Task(2, "yellow", results)).start();
new Thread(new Task(3, "green", results)).start();
new Thread(new Task(4, "blue", results)).start();
new Thread(new Task(5, "indigo", results)).start();
new Thread(new Task(6, "violet", results)).start();
}
}
class Results {
private List<String> results = new ArrayList<String>();
private int i = 0;
public synchronized void submit(int order, String result) {
while (results.size() <= order) results.add(null);
results.set(order, result);
while ((i < results.size()) && (results.get(i) != null)) {
System.out.println("result delivered: " + i + " " + results.get(i));
++i;
}
}
}
class Task implements Runnable {
private final int order;
private final String result;
private final Results results;
public Task(int order, String result, Results results) {
this.order = order;
this.result = result;
this.results = results;
}
public void run() {
try {
Thread.sleep(Math.abs(result.hashCode() % 1000)); // simulate a long-running computation
}
catch (InterruptedException e) {} // you'd want to think about what to do if interrupted
System.out.println("task finished: " + order + " " + result);
results.submit(order, result);
}
}
If you need that fine-grained control, you should not use threads but instead look into using a suitable Executor with Callables or Runnables. See the Executors class for a wide selection.
A simple solution would be to use an array A of locks (one lock per thread). When thread i begins its executions, it acquires its associated lock A[i]. When it's ready to merge its results, it releases its lock A[i] and waits for locks A[0], A[1], ..., A[i - 1] to be released; then it merges the results.
(In this context, thread i means the i-th launched thread)
I don't know what classes to use in Java, but it must be easy to implement. You can begin reading this.
If you have more questions, feel free to ask.
public static void main(String[] args) throws InterruptedException{
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r,"A");
Thread t2 = new Thread(r,"B");
Thread t3 = new Thread(r,"C");
t1.start();
Thread.sleep(1000);
t2.start();
Thread.sleep(1000);
t3.start();
}
Control of thread execution order may be implemented quite easily with the semaphores. The code attached is based on the ideas presented in Schildt's book on Java (The complete reference....).
// Based on the ideas presented in:
// Schildt H.: Java.The.Complete.Reference.9th.Edition.
import java.util.concurrent.Semaphore;
class Manager {
int n;
// Initially red on semaphores 2&3; green semaphore 1.
static Semaphore SemFirst = new Semaphore(1);
static Semaphore SemSecond = new Semaphore(0);
static Semaphore SemThird = new Semaphore(0);
void firstAction () {
try {
SemFirst.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("First: " );
System.out.println("-----> 111");
SemSecond.release();
}
void secondAction() {
try{
SemSecond.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("Second: ");
System.out.println("-----> 222");
SemThird.release();
}
void thirdAction() {
try{
SemThird.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("Third: ");
System.out.println("-----> 333");
SemFirst.release();
}
}
class Thread1 implements Runnable {
Manager q;
Thread1(Manager q) {
this.q = q;
new Thread(this, "Thread1").start();
}
public void run() {
q.firstAction();
}
}
class Thread2 implements Runnable {
Manager q;
Thread2(Manager q) {
this.q = q;
new Thread(this, "Thread2").start();
}
public void run() {
q.secondAction();
}
}
class Thread3 implements Runnable {
Manager q;
Thread3(Manager q) {
this.q = q;
new Thread(this, "Thread3").start();
}
public void run() {
q.thirdAction();
}
}
class ThreadOrder {
public static void main(String args[]) {
Manager q = new Manager();
new Thread3(q);
new Thread2(q);
new Thread1(q);
}
}
This can be done without using synchronized keyword and with the help of volatile keyword. Following is the code.
package threadOrderingVolatile;
public class Solution {
static volatile int counter = 0;
static int print = 1;
static char c = 'A';
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread[] ths = new Thread[4];
for (int i = 0; i < ths.length; i++) {
ths[i] = new Thread(new MyRunnable(i, ths.length));
ths[i].start();
}
}
static class MyRunnable implements Runnable {
final int thID;
final int total;
public MyRunnable(int id, int total) {
thID = id;
this.total = total;
}
#Override
public void run() {
while(true) {
if (thID == (counter%total)) {
System.out.println("thread " + thID + " prints " + c);
if(c=='Z'){
c='A';
}else{
c=(char)((int)c+1);
}
System.out.println("thread " + thID + " prints " + print++);
counter++;
} else {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// log it
}
}
}
}
}
}
Following is the github link which has a readme, that gives detailed explanation about how it happens.
https://github.com/sankar4git/volatile_thread_ordering