Singelton pattern with multithread - java

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.

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..

Join a two different ExecutorService

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.

Understanding wait() and notify() methods

I'm trying to understand how Java's wait and notify methods work. As per the documentation, wait() causes thread to wait for subsequent calls to notify() or notifyAll() methods but for some reason notify doesn't interrupt "waiting":
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("thread1 is started, waiting for notify()");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e.getLocalizedMessage());
}
}
System.out.println("waiting is over");
}
});
thread1.start();
// unblock thread1 in 2 seconds
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (thread1) {
thread1.notify();
}
}
You need to notify the object that is being waited on, not the thread that is waiting.
In your case the object waited on is an instance of an anonymous inner class, which is problematic because you cannot easily obtain a reference to it in order to notify it. You could solve this by extending Thread directly:
Thread thread1 = new Thread() {
#Override
public void run() {
System.out.println("thread1 is started, waiting for notify()");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e.getLocalizedMessage());
}
}
System.out.println("waiting is over");
}
};
Now the this (in synchronized (this)) refers to the thread itself, and the wait is called on the thread object too. In this case your current call to notify should be fine, since it notifies the same object (which happens in this case to be the thread that is waiting - but just to be clear, that need not be the case).
It isn't considered good practice to use an object for synchronisation that may also be used elsewhere; instances of Thread would be an example of this, and in fact the documentation specifically advises against it:
It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Also, you should correctly handle spurious wakeup; that is, wait may return because notify/notifyAll was called elsewhere or perhaps was not even called at all. As the documentation also says:
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops [...]
Therefore, your example should really use a separate variable to track whether the wakeup was intentional (due to an explicit notify) or not.
for some reason notify doesn't interrupt "waiting":
#davmac's answer is correct but for posterity, there are some other ways you can do it because extending Thread and calling wait() and notify() on the Thread object is not recommended.
The best way would be to create a lock object. Making your lock objects final is always a good pattern although here it is also necessary to use it in the inner class.
final Object lock = new Object();
Thread thread1 = new Thread(new Runnable() {
...
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
// always a good pattern
Thread.currentThread().interrupt();
System.out.println(e.getLocalizedMessage());
}
}
...
}
...
synchronized (lock) {
lock.notify();
}
// might as well wait for it to finish
thread1.join();

Deadlocks using wait and notify

I am trying to understand how deadlocks are created. I've understood that by using two threads on two synchronized methods, a deadlock can be created.
Went through many examples from the net.
Can a deadlock be created with wait and notify?
Every time a thread is on wait, it will be notified. So how does this end up in a deadlock?
Illustration of an example will be helpful.
Deadlock is caused when two threads try to obtain the same, multiple locks in different order:
// T1
synchronized (A) {
synchronized (B) {
// ...
}
}
// T2
synchronized (B) {
synchronized (A) {
// ...
}
}
The only way to prevent deadlocks is to make sure that all threads obtain locks in the same order--either they all do A then B, or they all do B then A.
If you don't have multiple locks, then you don't have a deadlock. However, you can get thread starvation or other things that may look similar to deadlock.
Say thread 1 enters a synchronized block on method A and then waits. Thread 2 then attempts to enter the synchronized block on method A. Thread 1 is waiting for a notify, and thread 2 is waiting on the synchronized block. Everything is now waiting. Some other thread will have to notify the object on which thread 1 is waiting. This is just one scenario that can create a deadlock. There are all kinds of ways to do it.
A thread which is on wait will not be notified unless some code explicitly notifies it. Therefore the example you are looking for is absolutely trivial:
public static void main(String[] args) {
synchronized(String.class) {
String.class.wait();
}
}
and this hangs forever. Technically, though, it is not a deadlock, which requires two or more threads involved in a closed cycle where each thread waits for the next one to unblock it.
Something close to wait/notify deadlock:
public class Example
{
volatile boolean isNotified = false;
public synchronized void method1() {
try
{
isNotified = false;
while (!isNotified)
wait();
notifyAll();
System.out.println("Method 1");
} catch (InterruptedException e) {/*NOP*/}
}
public synchronized void method2() {
try {
isNotified = true;
while (isNotified)
wait();
notifyAll();
System.out.println("Method 2");
} catch (InterruptedException e) {/*NOP*/}
}
public static void main(String[] args)
{
Example example = new Example();
Thread thread1 = new Thread()
{
public void run()
{
example.method1();
}
};
Thread thread2 = new Thread()
{
public void run()
{
example.method2();
}
};
thread1.start();
thread2.start();
}
}

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