While trying to understand the differences between Phaser and CyclicBarrier I have come across some links
Difference between Phaser and CyclicBarrier and
https://www.infoq.com/news/2008/07/phasers/
I read that the Phaser is compatible with Fork/Join interface while CyclicBarrier is not, here is a code to demonstrate this:
Phaser
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
Phaser phaser = new Phaser(16){
#Override
protected boolean onAdvance(int phase, int registeredParties) {
return phase ==1 || super.onAdvance(phase, registeredParties);
}
};
System.out.println("Available Processors: "+Runtime.getRuntime().availableProcessors());
ExecutorService executorService = ForkJoinPool.commonPool(); // Runtime.getRuntime().availableProcessors() -1
for (int i = 0; i < 16; i++) {
final int count = 0;
executorService.submit(() -> {
while (!phaser.isTerminated()) {
try {
Thread.sleep(ThreadLocalRandom.current().nextInt(300, 2000));
System.out.println(Thread.currentThread().getName() + count + " ... ");
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + count + " ... continues ... ");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDownLatch.countDown();
});
}
countDownLatch.await();
}
CyclicBarrier
public static void main(String[] args) throws InterruptedException {
AtomicInteger phases = new AtomicInteger();
CountDownLatch countDownLatch = new CountDownLatch(1);
CyclicBarrier cyclicBarrier = new CyclicBarrier(16, () -> phases.incrementAndGet());
ExecutorService executorService = ForkJoinPool.commonPool();
for (int i = 0; i < 16; i++) {
executorService.submit(() -> {
while (phases.get() < 1) {
try {
Thread.sleep(ThreadLocalRandom.current().nextInt(300, 2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println(Thread.currentThread().getName() + " Ok, I am waiting ");
cyclicBarrier.await();
System.out.println(Thread.currentThread().getName() + " continued it's way ... ");
} catch (BrokenBarrierException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
});
}
countDownLatch.await();
}
Explanation:
The two codes runs a fork/join thread pool, this mean that the threads are daemon threads and this is why I use CountDownLatch. The method commonPool() will create a thread pool with threads equal to Runtime.getRuntime().availableProcessors(), mine are 12, so it will create 12 threads. Both Phaser and CyclicBarrier in the two examples define 16 parties i.e they need 16 calls to await(), in the cyclic barrier, and arriveAndAwaitAdvance() in the Phaser, to move on.
In the example with the phaser, when the 12th thread blocks the fork/join will spawn more threads, it will create more threads, hence the phaser will eventually terminate. However, with CyclicBarrier when the 12th threads reach await() the program stops and never advances, it hangs. Obviously, because the barrier needs 16 calls, to make the threads advances, and only 12 are made by the created threads. The thread pool will not create more thread to advance the CyclicBarrier as it does with the Phaser.
The question:
How does the fork/join manages to create more threads with the Phaser but not with the CyclicBarrier?
Why the methods arriveAndAwaitAdvance() made the thread pool create new threads, and how, but metho await() did not cause the threadpool to create more threads?
The Phaser is able to do this because it internally calls ForkJoinPool.managedBlock(ManagedBlocker) when blocking a thread.
This API of the ForkJoinPool is accessible to anyone, so you can easily enhance your CyclicBarrier version to use it, and remove thread starvation. For example with something in the vibe of:
ForkJoinPool.managedBlock(new ManagedBlocker() {
boolean isReleasable = false;
#Override
public boolean block() throws InterruptedException {
try {
cyclicBarrier.await();
} catch (BrokenBarrierException aE) {
throw new IllegalStateException(aE);
}
return isReleasable = true;
}
#Override
public boolean isReleasable() {
return isReleasable;
}
});
Related
How to wait for all tasks to be completed when they are submitted using
ExecutorService.execute() . There is a function called awaitTermination
But a timeout has to be provided in it. Which is not a guarantee that when this
returns all the tasks would have been finished. Is there a way to achieve this ?
If you read the javadoc of the ExecutorService.awaitTermination (or look at the method signature) you will see it returns a boolean. This boolean indicates if the Executor terminated or not. You can use that information to create a while loop to determine if it has been terminated or not.
ExecutorService executor = ...
executor.shutdown(); // close the executor and don't accept new tasks
while (!executor.awaitTermination(100, TimeUnit.MILLISECONDS) {}
Something like this will stop the executor and wait until it terminated and all tasks have finished.
execute method does not return anything. You can use the submit method which returns a result of type Future.
Future<String> future =
executorService.submit(callableTask/runnableTask);
If you use class ThreadPoolExecutor or any of its children you have a method there getActiveCount() that returns the number of threads that are actively executing tasks. So you can poll that method until it gets to 0, which would mean that all tasks have been completed and no new tasks are currently executing. However, what if some task gets stuck? I think you will have to also give some timeout in order to prevent infinite loop in this case. The biggest advantage of this idea is that you are not required to invoke shutdown method
There are several approaches.
You can call first ExecutorService.shutdown and then ExecutorService.awaitTermination which returns:
true if this executor terminated and false if the timeout elapsed
before termination
So:
There is a function called awaitTermination But a timeout has to be
provided in it. Which is not a guarantee that when this returns all
the tasks would have been finished. Is there a way to achieve this ?
You just have to call awaitTermination in a loop.
Using awaitTermination
A full example with this implementation:
public class WaitForAllToEnd {
public static void main(String[] args) throws InterruptedException {
final int total_threads = 4;
ExecutorService executor = Executors.newFixedThreadPool(total_threads);
for(int i = 0; i < total_threads; i++){
executor.execute(parallelWork(100 + i * 100));
}
int count = 0;
// This is the relevant part
// Chose the delay most appropriate for your use case
executor.shutdown();
while (!executor.awaitTermination(100, TimeUnit.MILLISECONDS)) {
System.out.println("Waiting "+ count);
count++;
}
}
private static Runnable parallelWork(long sleepMillis) {
return () -> {
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException e) {
// Do Something
}
System.out.println("I am Thread : " + Thread.currentThread().getId());
};
}
}
Using CountDownLatch
Another option is to create a CountDownLatch with a count equals to the number of parallel tasks. Each thread calls countDownLatch.countDown();, while the main thread calls countDownLatch.await();.
A full example with this implementation:
public class WaitForAllToEnd {
public static void main(String[] args) throws InterruptedException {
final int total_threads = 4;
CountDownLatch countDownLatch = new CountDownLatch(total_threads);
ExecutorService executor = Executors.newFixedThreadPool(total_threads);
for(int i = 0; i < total_threads; i++){
executor.execute(parallelWork(100 + i * 100, countDownLatch));
}
countDownLatch.await();
System.out.println("Exit");
executor.shutdown();
}
private static Runnable parallelWork(long sleepMillis, CountDownLatch countDownLatch) {
return () -> {
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException e) {
// Do Something
}
System.out.println("I am Thread : " + Thread.currentThread().getId());
countDownLatch.countDown();
};
}
}
Using Cyclic Barrier
Another approach is to use a Cyclic Barrier
public class WaitForAllToEnd {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
final int total_threads = 4;
CyclicBarrier barrier = new CyclicBarrier(total_threads+ 1);
ExecutorService executor = Executors.newFixedThreadPool(total_threads);
for(int i = 0; i < total_threads; i++){
executor.execute(parallelWork(100 + i * 100, barrier));
}
barrier.await();
System.out.println("Exit");
executor.shutdown();
}
private static Runnable parallelWork(long sleepMillis, CyclicBarrier barrier) {
return () -> {
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException e) {
// Do Something
}
System.out.println("I am Thread : " + Thread.currentThread().getId());
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
// Do something
}
};
}
}
There are other approaches but those would require changes to your initial requirements, namely:
How to wait for all tasks to be completed when they are submitted
using ExecutorService.execute() .
I am trying to manipulate this program to print ":---)))))" repeatedly.
I understand that a semaphore is a way of controlling threads, and acquire essentially acquires a permit (reads) and release returns a permit back to the semaphore. (writes)
I've tried manipulating the number of permits when initializing the semaphores, but I am not understanding how to sync them together because I can't figure out how exactly the semaphores operate with how they acquire and release.
I am looking for a helpful explanation that pertains to Java in the context of only using semaphores, acquire and release and how they work together to properly put the threads "in sync"
import java.lang.Thread;
import java.util.concurrent.*;
public class ThreadSync {
private static boolean runFlag = true;
private static Semaphore canPrintC = new Semaphore(1);
private static Semaphore canPrintD = new Semaphore(0);
private static Semaphore canPrintP = new Semaphore(0);
public static void main(String [] args) {
// Create and start each runnable
Runnable task1 = new TaskPrintC();
Runnable task2 = new TaskPrintD();
Runnable task3 = new TaskPrintP();
Thread thread1 = new Thread(task1);
Thread thread2 = new Thread(task2);
Thread thread3 = new Thread(task3);
thread1.start();
thread2.start();
thread3.start();
// Let them run for 500 ms
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
runFlag = false;
thread3.interrupt();
thread2.interrupt();
thread1.interrupt();
}
public static class TaskPrintC implements Runnable {
public void run() {
while (runFlag) {
try {
canPrintC.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf("%s", ":");
canPrintD.release();
}
}
}
public static class TaskPrintD implements Runnable {
public void run() {
while (runFlag) {
try {
canPrintD.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf("%s", "-");
canPrintP.release();
}
}
}
public static class TaskPrintP implements Runnable {
public void run() {
while (runFlag) {
try {
canPrintP.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf("%s", ")");
canPrintC.release();
}
}
}
}
Threads execute tasks and semaphores can help you to let tasks (or runnable objects) know each other's state (e.g. task A waits for input from task B and task B can signal task A that input is available). The difference between a task and a thread is important.
To stress this point, I have taken your example and made one runnable class that performs the task of printing a character a number of times (configured via variables in the constructor). To mimic the serialized behavior (tasks run after each other), the runnable is also aware of the next runnable that should perform the print task.
To complete the example I also ensured that the thread that is executing the main-method is aware of when the tasks have completed, so that the program stops at the proper time. A CountDownLatch is used in this case (a CountDownLatch is a very simple variation of a Semaphore).
The example below might be a bit hard to understand, but it shows some good practices (re-use code, using a stop-flag instead of interrupt, use an executor to run tasks, cleanup and stop tasks in case of error). It also shows how Semaphores can orchestrate the execution of tasks.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class ChainedSemaphoreTasks {
// amount of times chained tasks are executed.
static int MAX_CHAINED_LOOPS = 3;
// helper to let main-thread know when chained loops have been executed.
final static CountDownLatch MAX_LOOPS_REACHED = new CountDownLatch(1);
public static void main(String[] args) {
String printChars = ":-)";
int[] repeatChars = { 1, 3, 5};
List<ChainedTask> tasks = buildTasks(printChars, repeatChars);
ExecutorService executor = Executors.newCachedThreadPool();
for (ChainedTask task : tasks) {
executor.execute(task);
}
try {
// Trigger first task to start running.
tasks.get(0).triggerPrintTask();
// wait for loop to complete, but not too long.
if (!MAX_LOOPS_REACHED.await(5000L, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Chained tasks loop did not complete within timeout.");
}
long waitStart = System.currentTimeMillis();
executor.shutdown();
if (executor.awaitTermination(1000L, TimeUnit.MILLISECONDS)) {
System.out.println("All tasks stopped within " + (System.currentTimeMillis() - waitStart) + " ms.");
} else {
throw new RuntimeException("Not all chained tasks stopped within timeout.");
}
} catch (Exception e) {
e.printStackTrace();
// cleanup
try {
tasks.get(0).stop();
} catch (Exception e2) {
e2.printStackTrace();
}
executor.shutdownNow();
}
}
static List<ChainedTask> buildTasks(String printChars, int[] repeatChars) {
List<ChainedTask> tasks = new ArrayList<ChainedTask>();
int maxTasks = printChars.length();
if (maxTasks != repeatChars.length) {
throw new IllegalArgumentException("Amount of repeats per pritn character must match amount of characters.");
}
for (int i = 0; i < maxTasks; i++) {
ChainedTask task = new ChainedTask(printChars.charAt(i), repeatChars[i]);
tasks.add(task);
if (i > 0) {
tasks.get(i - 1).setNextTask(task);
}
}
// make last task trigger first task - creates an endless loop.
tasks.get(maxTasks - 1).setNextTask(tasks.get(0));
tasks.get(maxTasks - 1).setLastTask(true);
return tasks;
}
static AtomicInteger chainedLoopsCount = new AtomicInteger();
static class ChainedTask implements Runnable {
// Semaphore to trigger execution
Semaphore performTask = new Semaphore(0);
// If stop is true, task must finish.
// stop must be volatile to ensure updated value is always visible.
volatile boolean stop = false;
// The last task is responsible for stopping execution
boolean lastTask;
// The next task to run after this task.
ChainedTask nextTask;
char printChar;
int repeatAmount;
ChainedTask(char printChar, int repeatAmount) {
this.printChar = printChar;
this.repeatAmount = repeatAmount;
System.out.println("Created " + printChar + " / " + repeatAmount);
}
void triggerPrintTask() {
performTask.release(repeatAmount);
}
void stop() {
// first indicate to stop
stop = true;
// then release a permit to pickup the stop sign.
performTask.release();
// also stop next task, unless this is the last task
if (!isLastTask()) {
getNextTask().stop();
}
}
#Override
public void run() {
try {
while (!stop) {
runTask();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Stopped " + printChar + " / " + repeatAmount);
}
void runTask() throws Exception {
// wait for our turn
performTask.acquire();
// must check 'stop' after getting permit, see the stop-method:
// first stop is set to true and then a permit is released.
if (stop) {
return;
}
// print text for loop-amount
do {
System.out.print(printChar);
} while (performTask.tryAcquire());
if (isLastTask()) {
System.out.println();
// check if we should stop
if (chainedLoopsCount.incrementAndGet() >= MAX_CHAINED_LOOPS) {
// since this is the last task, the next task is the first task.
// stopping the first task will call the stop-method on all tasks, including this one.
getNextTask().stop();
// signal main-thread we are done.
MAX_LOOPS_REACHED.countDown();
}
// Sleep for a long time to test what happens when last task hangs.
// Should trigger the "cleanup" code in the main method.
// Thread.sleep(10000);
}
// trigger next chained task to run
// this has no effect if next chained task was stopped
getNextTask().triggerPrintTask();
}
void setNextTask(ChainedTask nextTask) {
this.nextTask = nextTask;
}
ChainedTask getNextTask() {
return nextTask;
}
void setLastTask(boolean lastTask) {
this.lastTask = lastTask;
}
boolean isLastTask() {
return lastTask;
}
}
}
Semaphore – to solve Producer/Consumer problem
A high level explanation of semaphore.
A semaphore contains a count indicating whether a resource is locked or available. Semaphore is a signaling mechanism (“I am done, you can carry on.”). The resource itself may not be thread safe.
Producer
semObject.Post(); // Send the signal
Increase the semaphore count by 1. If a thread is waiting on the
specified semaphore, it is awakened.[1]
Consumer
semObject.Wait(); // Wait for the signal
When the semaphore count is zero, the thread calling this function
will wait for the semaphore. When the semaphore count is nonzero, the
count will be decremented by 1 and the thread calling this function
will continue.[1]
Reference
[1] Massa, Anthony J., Embedded software development with eCos, Pearson Education, Inc., 2002
I want the threads to run in a particular order. Suppose I have three thread T1, T2, T2 .
T1 prints 0
T2 prints 1
T3 prints 2
I want the output in the order 0 1 2, 0 1 2 for certain number of time.
If there are two threads T1 and T2. Printing 0 1, 0 1... can be done using Producer-Consumer Problem using synchronization.
Create a class UnitOfWork:
public class UnitOfWork implements Runnable
{
String text;
public UnitOfWork(String text){
this.text = text;
}
public void run(){
System.out.println(text);
}
}
And then create a single thread executor service:
ExecutorService executor = ExecutorService.newSingleThreadExecutor();
which you will use like this:
UnitOfWork uow0 = new UnitOfWork("0");
UnitOfWork uow1 = new UnitOfWork("1");
UnitOfWork uow2 = new UnitOfWork("2");
for(int i = 0; i < 5; i++){
executor.submit(uow0);
executor.submit(uow1);
executor.submit(uow2);
}
When you are unhappy with the single thread, you can start using multiple thread executor service, which will in fact run tasks concurrently.
Using the method join() in the thread class you can achieve this.
The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,
t.join();
causes the current thread to pause execution until t's thread terminates. Overloads of join allow the programmer to specify a waiting period. However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.
Like sleep, join responds to an interrupt by exiting with an InterruptedException.
Use Thread.join to ensure it terminates before the next thread starts.
public static void main(String[] args) throws InterruptedException {
final Thread th1 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread th2 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread th3 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
th1.start();
th1.join();
th2.start();
th2.join();
th3.start();
}
This is a minimalist piece of code which does literally what you asked for. It relies on the wait-notify mechanism.
I stand by my assesment that you do not need any threads to meet your requirement. A simple loop which prints 0-1-2 is all you really need.
import static java.lang.Thread.currentThread;
public class A {
static int coordinator, timesPrinted;
static final int numThreads = 3, timesToPrint = 300;
public static void main(String[] args) {
for (int i = 0; i < numThreads; i++) {
final int myId = i;
new Thread(new Runnable() { public void run() {
while (true) synchronized (A.class) {
if (coordinator%numThreads == myId) {
System.out.println(myId+1);
coordinator++;
if (timesPrinted++ > timesToPrint) currentThread().interrupt();
A.class.notifyAll();
}
try {A.class.wait();} catch (InterruptedException e) {break;}
}
}}).start();
}
}
}
I have a thread which must wait several objects from different threads.
#Override
public void run() {
while (true) {
for (BackgroundTask task : tasks) {
synchronized (task) {
if (task.isReady()) {
task.doTask();
}
}
}
}
}
But it is a stupid use of CPU time.
How to wait several objects?
IMO CountDownLatch would be a good way of going about it. Quoting from the Javadoc:
class Driver2 { // ...
void main() throws InterruptedException {
CountDownLatch doneSignal = new CountDownLatch(N);
Executor e = ...
for (int i = 0; i < N; ++i) // create and start threads
e.execute(new WorkerRunnable(doneSignal, i));
doneSignal.await(); // wait for all to finish
}
}
class WorkerRunnable implements Runnable {
private final CountDownLatch doneSignal;
private final int i;
WorkerRunnable(CountDownLatch doneSignal, int i) {
this.doneSignal = doneSignal;
this.i = i;
}
public void run() {
try {
doWork(i);
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() { ... }
}
Please use notifyaAll() instead of notify() because notify wakes up single thread where as notifyAll() wakes up all the waiting threads.
If you can modify the BackgroundTask class, have it notify your runner when it is ready. Add a queue to your runner class, and each time a task is ready, it can add itself to the queue and notify it.
The runner class then waits on the queue when it is empty, and pulls items out of it to run when it is not.
You can utilize notify() and wait() on the Object. How you use it depends on the struture of your program.
I have a requirement for a task to be executed asynchronously while discarding any further requests until the task is finished.
Synchronizing the method just queues up the tasks and doesn't skip. I initially thought to use a SingleThreadExecutor but that queues up tasks as well. I then looked at the ThreadPoolExecutor but it reads the queue to get the task to be executed and therefore will have one task executing and a minimum of one task queued (the others can be discarded using ThreadPoolExecutor.DiscardPolicy).
The only thing I can think off is to use a Semaphore to block the queue. I've come with the following example to show what I'm trying to achieve. Is there a simpler way? Have I missed something obvious?
import java.util.concurrent.*;
public class ThreadPoolTester {
private static ExecutorService executor = Executors.newSingleThreadExecutor();
private static Semaphore processEntry = new Semaphore(1);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 20; i++) {
kickOffEntry(i);
Thread.sleep(200);
}
executor.shutdown();
}
private static void kickOffEntry(final int index) {
if (!processEntry.tryAcquire()) return;
executor.
submit(
new Callable<Void>() {
public Void call() throws InterruptedException {
try {
System.out.println("start " + index);
Thread.sleep(1000); // pretend to do work
System.out.println("stop " + index);
return null;
} finally {
processEntry.release();
}
}
}
);
}
}
Sample output
start 0
stop 0
start 5
stop 5
start 10
stop 10
start 15
stop 15
Taking axtavt's answer and transforming the above example gives the following simpler solution.
import java.util.concurrent.*;
public class SyncQueueTester {
private static ExecutorService executor = new ThreadPoolExecutor(1, 1,
1000, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
new ThreadPoolExecutor.DiscardPolicy());
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 20; i++) {
kickOffEntry(i);
Thread.sleep(200);
}
executor.shutdown();
}
private static void kickOffEntry(final int index) {
executor.
submit(
new Callable<Void>() {
public Void call() throws InterruptedException {
System.out.println("start " + index);
Thread.sleep(1000); // pretend to do work
System.out.println("stop " + index);
return null;
}
}
);
}
}
It looks like executor backed by SynchronousQueue with desired policy does what you want:
executor = new ThreadPoolExecutor(
1, 1,
1000, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
new ThreadPoolExecutor.DiscardPolicy());
if there is no queue, there is no need for an executor i'd say. using a semaphore alone seems enough. i'm using the code below to avoid running the same code when it is already running. just make sure the semaphore is static volatile, which makes the semaphore the only semaphore for the class and propagates the semaphore reference to other threads' heap as soon as it is changed
if (this.getSemaphore().tryAcquire()) {
try {
process();
} catch (Exception e) {
} finally {
this.getSemaphore().release();
}
}
else {
logger.info(">>>>> Job already running, skipping go");
}