Join a two different ExecutorService - java

I wanted to join two threads that are getting executed in ExecutorService.
public class CURD {
public static ExecutorService executorService = Executors.newCachedThreadPool();
#Autowired
Logging logging;
public void Update(List<? extends HBase> save, List<? extends HBase> delete) {
Thread t = new Thread(() -> {
System.out.println("Started Main Thread...");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End Main Thread...");
},"Thread-1");
logging.setPredecessor(t);
executorService.submit(t);
}
}
Second Class:
This class thread should wait for the first thread to complete.
But it doesn't wait for the first thread to complete.
I am not sure if this is the right way to do it.
Please can someone let me know how to join two threads that are getting executed in an ExecutorService?
import static com.demo.executorService;
public class Logging {
private Thread predecessor;
public void setPredecessor(Thread t) {
this.predecessor = t;
}
private void loggingInfo() {
Thread run = new Thread( () ->{
try {
if (predecessor != null) {
System.out.println(Thread.currentThread().getName() + " Started");
predecessor.join();
System.out.println(Thread.currentThread().getName() + " Finished");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
addTask(run);
}
public void addTask(Runnable run) {
System.out.println("Runnable Thread logAround.....");
CompletableFuture.runAsync((run), executorService).exceptionally(ex -> {
System.out.println("exception occurred " + ex);
return null;
});
}
}

If one wants to synchronize among a set of threads one can use
the Java CyclicBarrier class:
A synchronization aid that allows a set of threads to all wait for
each other to reach a common barrier point. CyclicBarriers are useful
in programs involving a fixed sized party of threads that must
occasionally wait for each other. The barrier is called cyclic because
it can be re-used after the waiting threads are released.
To achieve that, first create the CyclicBarrier object with the correspondent number of parties, namely:
private final CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_PARIES);
Formally from the Java doc one can read that parties are:
the number of threads that must invoke {#link #await} before the barrier is tripped
Informally, parties are the number of threads that will have to call the cyclic barrier and wait, before all of them can move forward.
Afterward, you need to pass the barrier instance object reference to each of the threads that should wait, and invoke wait (i.e., barrier.await()), accordingly. Something as follows:
public void Update(..., CyclicBarrier barrier) {
Thread t = new Thread(() -> {
System.out.println("Started Main Thread...");
try {
Thread.sleep(1500);
barrier.await(); // <--- wait on the barrier
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("End Main Thread...");
},"Thread-1");
...
}
Repeat this process to the other threads that must wait. Ensure that the number of parties (i.e., NUMBER_OF_PARIES) matches the number of threads that should wait on the cyclic barrier, otherwise deadlocks will occur.
Now that you are using the cyclic barrier you can clean up some parts of your code, for instance, you can remove all the logic related to the field predecessor of the Logging class.
If you just want to make Thread 2 wait for Thread 1, then you can use CountDownLatch, instead.
A synchronization aid that allows one or more threads to wait until a
set of operations being performed in other threads completes. A
CountDownLatch is initialized with a given count. The await methods
block until the current count reaches zero due to invocations of the
countDown() method, after which all waiting threads are released and
any subsequent invocations of await return immediately. This is a
one-shot phenomenon -- the count cannot be reset. If you need a
version that resets the count, consider using a CyclicBarrier.
First create the CountDownLatch object with only 1 count:
private final CountDownLatch block_thread2 = new CountDownLatch(1);
and pass it to the Thread 2, and since you want this thread to wait for the Thread 1, call block_thread2.await();
Thread run = new Thread( () ->{
try {
....
block_thread2.await(); // wait for Thread 2
} catch (InterruptedException e) {
// deal with it
}
});
...
and to the Thread 1 add wait.countDown();:
public void Update(...) {
Thread t = new Thread(() -> {
System.out.println("Started Main Thread...");
try {
Thread.sleep(1500);
wait.countDown();
} catch (InterruptedException e) {
// deal with it
}
System.out.println("End Main Thread...");
},"Thread-1");
...
}
So, in this manner, Thread 2 will wait for Thread 1, but Thread 1 will never wait for Thread 2.

Related

Using synchronized blocks, notify() and wait() the right way

I'm curious to submit here a short example I made and hopefully have someone able to explain to me one thing: is it possible to use the wait() and notify() inside a synchronized block without having to declare threads explicitly? (AKA: not using dedicated threads).
Here's the example:
public class mutex {
private Object mutex = new Object();
public mutex(Object mutex) {
this.mutex = mutex;
}
public void step1() throws InterruptedException {
System.out.println("acquiring lock");
synchronized(mutex) {
System.out.println("got in sync block");
System.out.println("calling wait");
mutex.wait();
System.out.println("wait finished ");
}
}
public void step2() throws InterruptedException{
System.out.println("acquiring lock");
synchronized(mutex){
System.out.println("got in sync block");
System.out.println("calling notify");
mutex.notify();
System.out.println("notify called");
}
}
Those two simple step are just prints for logging and what should be happening.
The idea is to be able to call a wait() in step1 and be able to complete the call once step2 has been called with its notify().
Now, as far as I understood the whole thing, this is the right way to do what I want to do:
public void go1() {
Object mutex = new Object();
mutex m = new mutex(mutex);
Thread t1 = new Thread(()->{
try {
m.step1();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(()->{
try {
Thread.sleep(1000);
m.step2();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
}
and finally the main
public static void main(String[] args) {
Object mutex = new Object();
new mutex(mutex).go1();
//new mutex(mutex).go2();
}
The above code works and shows what I am expecting:
acquiring lock
got in sync block
calling wait
acquiring lock
got in sync block
calling notify
notify called
wait finished
I get why it works. This is what I expected to happen and how I have been taught to do this. The question comes now as I will paste the second variant of the main function I wanted to test - this one just hangs when the wait() is called.
public void go2() {
Object mutex = new Object();
mutex m = new mutex(mutex);
try {
m.step1();
Thread.sleep(1000);
m.step2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Why does this hang?
Is it because there is just one thread doing everything and it goes into waiting state after the wait() is called?
I know that when wait is called on the monitor object it should also release the lock, so why in this case the program can't get to call the step2()?
Is there a way to use the my second go() function to achieve this process or is it impossible for it to work?
TLDR just so I am making sure I can be understood: do I have to use dedicated threads to also use properly wait() and notify()? Because I seem to get deadlocks if I don't.
Thank you.
Once you call mutex#wait, the current thread is added to the wait set of object mutex. And thread will not execute any further instructions until it has been removed from mutex's wait set. That's why step2 cannot be executed by the current thread.
The current thread will be removed from the wait set and resume if other threads call mutex#notify/notifyAll. See JLS#WAIT for all situations in which the current thread can resume..

Singelton pattern with multithread

I read about sigelton pattern with multithreads and I found that is implemented use synchronized .
my question is can I use wait() + notify() or notifyAll() instead synchronized ??
and if yes which better synchronized or wait()+ notifyAll() ???
The methods wait and notify are only meaningful within a synchronized method/block.
Try this:
public static void main(String[] args) {
Object monitor = new Object();
try {
monitor.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
It will result in:
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
This is because the current thread does not own the monitor.
Now try this, and you're in business (although not a very useful business yet):
public static void main(String[] args) {
Object monitor = new Object();
synchronized (monitor) {
try {
monitor.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The thread now waits indefinitely for the notify that will never come.
Now try this:
public static void main(String[] args) {
Object monitor = new Object();
Thread a = new Thread(() -> {
try {
System.out.printf("Thread %s Waiting for notification%n", Thread.currentThread().getId());
synchronized (monitor) {
monitor.wait();
}
System.out.printf("Thread %s Received notification%n", Thread.currentThread().getId());
}
catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread b = new Thread(() -> {
try {
System.out.printf("Thread %s Sleeping three seconds%n", Thread.currentThread().getId());
Thread.sleep(3000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Thread %s Sending notification%n", Thread.currentThread().getId());
synchronized (monitor) {
monitor.notify();
}
});
a.start();
b.start();
}
Thread a synchronizes on the monitor and waits for a notification.
Thread b sleeps for three seconds, then synchronizes on the monitor and notifies.
Example output:
Thread 14 Waiting for notification
Thread 15 Sleeping three seconds
Thread 15 Sending notification
Thread 14 Received notification
The numbers are the thread ID's which I logged for clarity.
Now to your question about a singleton. There are several ways to enforce that there is only one instance of a class. Most commonly, a framework like Spring enforces single instances of its beans within the application context. This is an accept pragmatic approach. To enforce a singleton within a class loader, probably the best way is to use an enum because it avoids serialization issues, but it's often done with a private constructor and a static instance field. Note that this type of self-managed singletons is considered an anti-pattern by most.
A singleton is normally only unique within a class loader. If you are running on an application server there might be multiple class loaders so you have to be careful there about the context in which you want to be able to use this singleton. In such a situation it might be better to avoid the singleton and instead create a separate deployable service or repository to keep the data in.
If you do have a singleton and want to be able to access it in a thread-safe manner, you will have to synchronize all access to it. You don't necessarily need wait/notify for this. For example:
static long start = System.currentTimeMillis();
public static void main(String[] args) {
Object monitor = new Object();
Thread a = new Thread(() -> {
sleep(1000);
log("before synchronized block");
synchronized (monitor) {
log("entered synchronized block");
log("done");
}
});
Thread b = new Thread(() -> {
log("before synchronized block");
synchronized (monitor) {
log("entered synchronized block");
sleep(3000);
log("done");
}
});
a.start();
b.start();
}
private static void sleep(int millis) {
try {
log("sleeping for " + millis);
Thread.sleep(millis);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void log(String message) {
System.out.printf("At %s thread %s %s%n", (System.currentTimeMillis() - start), Thread.currentThread().getId(), message);
}
Example output:
At 2 thread 15 before synchronized block
At 14 thread 15 entered synchronized block
At 25 thread 14 sleeping for 1000
At 25 thread 15 sleeping for 3000
At 1038 thread 14 before synchronized block
At 3038 thread 15 done
At 3039 thread 14 entered synchronized block
At 3040 thread 14 done
Just by using synchronized already the access can be made exclusive. Only when a thread needs the results of another thread does wait/notify come into play.
can I use wait() + notify() or notifyAll() instead synchronized?
The answer is the same regardless of whether you are trying to implement a singleton or implement anything else.
No.
synchronized is a mechanism by which threads in a Java program can safely share variables. It provides two things:
It prevents threads from interfering with each other when they access the shared variables.
It ensures that updates to shared variables made by one thread will become visible to other threads in a predictable and timely way.
wait(), notify(), and notifyAll() are a mechanism by which one thread can notify other threads that it has changed shared variables in some particular way.
wait() or notify() or notifyAll() don't technically require the use of synchronized, but the Java language designers arbitrarily added that requirement as a reminder that, if you're going to notify another thread about something you did to shared variables, or even if you're only going to look at something that another thread did to them, you're going to need synchronized to safely access the variables.

How do I ensure that a thread is started before another thread?

I have 2 threads T1 and T2. T2 should start its work after it gets a message from T1. Both T1 and T2 are started in main(). T1 can't start T2.
This is what I have so far:
T1:
//do work1 which should be executed before work2
lock2.notify()
T2:
lock2.wait();
//do work2 which should be executed after work1 ends
The problem is that sometimes T1 is started before T2 and T2 never gets the notify sent by T1 and waits forever.
Can I use any existing concurrency utilities to achieve this signalling?
Thanks.
You need some synchronisation mechanism between the two threads. Below is an example where I use a CountDownLatch for that purpose. I defined a class SyncedThread which gets a CountDownLatch passed in the constructor.
In the main method I then create two instances of this class. The first, thread1 will run for 2 seconds, then signal the CountDownLatch and then do some dummy sleep for another 3 seconds.
The second instance thread2 will wait for the CountDownLatch and will then sleep 5 seconds simulating work.
thread2.start() method is called first, then the thread1.start() with a delay of 500ms, but by using the synchronisatio you will see in the output that actually thread2 is waiting for thread1.
public class ThreadStarterTest {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(1);
SyncedThread thread1 = new SyncedThread(latch, "thread 1") {
#Override
public void run() {
try {
System.out.println(getName() + " running");
Thread.sleep(2_000);
latch.countDown();
Thread.sleep(3_000);
System.out.println(getName() + " finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
SyncedThread thread2 = new SyncedThread(latch, "thread 2") {
#Override
public void run() {
try {
latch.await();
System.out.println(getName() + " running");
Thread.sleep(5_000);
System.out.println(getName() + " finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
try {
thread2.start();
Thread.sleep(500);
thread1.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static class SyncedThread extends Thread {
private final CountDownLatch latch;
public SyncedThread(final CountDownLatch latch, final String name) {
super(name);
this.latch = latch;
}
}
}
In general, whenever you use wait() and notify(), you should also have some sort of mechanism (such as a marker variable) to check to see if you're done waiting. From the Javadoc for wait():
[…] this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
In your case that means that you simply never enter the loop if you don't actually need to wait.
That said, you might want to reconsider launching both threads from main(); from your description, it's not obvious why you're doing it that way.
You should make T1 waits while t2 has not sent the message.
Add a shared variable to represent the message and use it in a while statement.
And after lock2.send(); invokelock2.notify();` in T2 in order to notify T1 if it waits for.
T1:
while (lock2.isNotSend()){
lock2.wait();
}
lock2.notify()
//do some work
T2:
// processing that sends the message
lock2.send();
lock2.notify();
lock2.wait();

Using thread for parallel processing in java

I need few of the functions in my program to run simultaneously. These processes returns records. But, the output of one is the input to the other. In such a case, if at a point of time function A takes some time to output some record to the function B, I need to the function B to wait till function A provides some records as input for this process. Can I achieve this simply by using the thread functionalities such as wait, join, etc.. Or Is there any other ways to achieve the same functionality.
Edited:
As per the below mentioned suggestions, If I use the producer-consumer algorithm with BlockingQueue,ExecutorService, Future and CountDownLatch, Can I achieve every functionalities I requested?
As mentioned above you can use blocking queue with producer consumer
OR
You can use countdown latch of the java concurrency to solve your problem.
How CountDownLatch works?
CountDownLatch.java class defines one constructor inside:
//Constructs a CountDownLatch initialized with the given count.
public void CountDownLatch(int count) {...}
This count is essentially the number of threads, for which latch should wait. This value can be set only once, and CountDownLatch provides no other mechanism to reset this count.
The first interaction with CountDownLatch is with main thread which is goind to wait for other threads. This main thread must call, CountDownLatch.await() method immediately after starting other threads. The execution will stop on await() method till the time, other threads complete their execution.
Other N threads must have reference of latch object, because they will need to notify the CountDownLatch object that they have completed their task. This notification is done by method : CountDownLatch.countDown(); Each invocation of method decreases the initial count set in constructor, by 1. So, when all N threads have call this method, count reaches to zero, and main thread is allowed to resume its execution past await() method.
Below is a simple example. After the Decrementer has called countDown() 3 times on the
CountDownLatch, the waiting Waiter is released from the await() call.
CountDownLatch latch = new CountDownLatch(3);
Waiter waiter = new Waiter(latch);
Decrementer decrementer = new Decrementer(latch);
new Thread(waiter) .start();
new Thread(decrementer).start();
Thread.sleep(4000);
public class Waiter implements Runnable{
CountDownLatch latch = null;
public Waiter(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Waiter Released");
}
}
public class Decrementer implements Runnable {
CountDownLatch latch = null;
public Decrementer(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
Thread.sleep(1000);
this.latch.countDown();
Thread.sleep(1000);
this.latch.countDown();
Thread.sleep(1000);
this.latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
In your case you can use callable to create thread instead of runnable as you need to get the retrun value from one thread and have to pass that value to second thread.
In most cases you do not need to use wait etc. All you need to do is choose a good safe structure to use to communicate between your threads,
In this specific case I would suggest one of the concurrent queuue implementations, perhaps a BlockingQueue such as ArrayBlockingQueue.
Java's Fork and Join looks suitable for the usecase specified in your Question.
See http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
Have a look at BlockingQueue classes and producer/consumer patterns.
The first thread is getting the work unit from an input blocking queue and putting its output to an output blocking queue (with size restrictions).
The second thread is doing the using this output queue as an input.
With this method you can also easialy adjust the number of threads.
Ensure the the work load per work unit is not to small.
This is similar to producer-consumer problem. You can use Java's BlockingQueue.
The process A will enqueue its results and the process B will wait until A's output is ready in the queue. When output of A is available, then B can read and consume it.
This looks like the consumer-producer-problem. As suggested by others you can use a BlockingQueue. Here is an example for how to use it:
public static void main(final String[] args) {
final ExecutorService producer = Executors.newSingleThreadExecutor();
final ExecutorService consumer = Executors.newSingleThreadExecutor();
final BlockingQueue<Integer> workpieces = new LinkedBlockingQueue<>();
producer.submit(new Runnable() {
#Override
public void run() {
final Random rand = new Random();
for (;;) {
try {
workpieces.put(rand.nextInt());
Thread.sleep(1000);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
});
consumer.submit(new Runnable() {
#Override
public void run() {
for (;;) {
try {
System.out.println("Got " + workpieces.take());
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
});
}
It generates a random number every second in the producer-thread which is printed by the consumer-thread.
You can use BlockingQueue between producer and consumer threads. The producer will keep on adding results to queue if it is not full, concurrently the consumer thread can process pending messages from queue.

About wait and notifyAll

I've this class:
public class MyThread implements Runnable {
private static boolean canAccess = true;
private Thread t;
public FirstThread(String name) {
t = new Thread(this);
t.setName(name);
}
public void start() {
t.start();
}
private synchronized void accessed(String name) throws InterruptedException {
if (canAccess) {
canAccess = false;
System.out.println("Accessed " + name);
try {
Thread.sleep(5000);
} catch (Exception e) {
}
canAccess = true;
System.out.println("NOTIFY: " + name);
notifyAll();
}
System.out.println("WAIT: " + name);
wait();
}
#Override
public void run() {
while (true) {
try {
accessed(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
And this is my output:
Accessed 1
WAIT: 3
WAIT: 5
WAIT: 7
WAIT: 9
WAIT: 0
WAIT: 2
WAIT: 4
WAIT: 6
WAIT: 8
NOTIFY: 1
WAIT: 1
and my app freeze (deadlock state).
Seems that the notifyAll method doesn't work. Where is my error?
My Main class.
public class Main {
public static void main(String[] args) {
MyThread [] threads = new MyThread[10];
for(int i=0;i<threads.length;i++) {
threads[i] = new MyThread(""+i);
threads[i].start();
}
}
}
wait means that the thread releases the lock and goes into a dormant state until another thread notifies it. notifyAll means that the thread tells all the other threads waiting on the lock being used in the current synchronized block to wake up and try to acquire the lock again. Your code example doesn't have any cases where multiple threads are trying to acquire the same lock so using wait and notifyAll here doesn't make any sense. There's nothing to wake up the thread once it calls wait.
One typical use of wait and notify: You might have many producers putting stuff in a queue, and consumer threads that take stuff out of the queue. The queue has a take method that the consumer calls, if the queue is empty then it calls wait and the consumer blocks. The queue has a put method that calls notifyAll when something goes into the queue so that any waiting consumer threads wake up.
There's a producer-consumer example of using wait and notifyAll in the Java tutorial.
Every Thread waits on it's own instance, that's why they all are stuck in one place.
If you had a private static Object LOCK = new Object(); and call LOCK.wait(); and LOCK.notify(); this could be another story.
I have also doubts about synchronized modifier for accessed() method. It's just doesn't have use in the described situation. I would better modify the "canAccess" variable in synchronized block.

Categories

Resources