Why no deadlock on the same object in this program - Java Multithreading - java

I have three classes below. Main, two threads and Obj whose methods are synchronized
public class DeadLocks {
public static void main(String[] args) {
SyncObj so = new SyncObj();
ThreadObj to = new ThreadObj(so);
ThreadObj1 to1 = new ThreadObj1(so);
to.start();
to1.start();
}
}
class SyncObj {
synchronized void foo() {
System.out.println("Foo Started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bar();
}
synchronized void bar() {
System.out.println("bar started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
foo();
}
}
class ThreadObj1 extends Thread {
SyncObj so;
public ThreadObj1(SyncObj so) {
this.so = so;
}
#Override
public void run() {
so.bar();
}
}
class ThreadObj extends Thread {
SyncObj so;
public ThreadObj(SyncObj so) {
this.so = so;
}
#Override
public void run() {
so.foo();
}
}
In the above code I'm calling synchronized methods on the same object. Both the methods are executing and calling each other simultaneously.There is no deadlock situation. Could anyone explain why? sorry for such a silly question.

As far as I can see, you are using the same object (so) for both the cases. So there is no case for a deadlock. You would need to lock on two or more objects wherein each critical section requires the lock other than the one that it is holding. That other lock is held by "another" thread.
Confusing, this will enlighten: "https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html"
You would never ever deadlock in a scenario that you describe. In this scenario there is only one so that is being shared and is being synchronized with.
Let me give you an example to illustrate:
Suppose Andy and Sandy are playing with two soccer balls B1 and B2.
Now further suppose that both Andy and Sandy have balls B1 and B2 in their possession respectively. For example Andy has ball B1 and Sandy has ball B2.
Now they devise a game wherein they need both the balls each.
Now Sandy wants ball B1 as well and at the same time, Andy wants B2.
And both of them cannot relinquish the balls that they hold. Andy will not give up B1 and vice-versa.
So both of them cannot continue and are stuck. We call this a deadlocked situation.
Hope this example helps. You could use your imagination to increase the number of balls in play to 3 or 4 (and so on..) and / or increase the number of players.

You do not get a deadlock because your program does not meet two of the four necessary conditions of forming it:
mutual exclusion - yes,
hold on partial allocation - no,
no pre-emption - yes,
circular dependency - no
You need at least two resources, "A" and "B", to form a deadlock. One thread should grab "A" and attempt to grab "B", while the other should grab "B", and attempt to grab "A".

I'm not sure why you expect a deadlock here. It's true that only one of objects has an access to synchronized section, but then it has this access as much as it wants. You can modify the code to make it clear:
public class DeadLocks {
public static void main(String[] args) {
SyncObj so = new SyncObj();
ThreadObj to = new ThreadObj(so);
ThreadObj1 to1 = new ThreadObj1(so);
to.start();
to1.start();
}
}
class SyncObj {
synchronized void foo(String msg) {
System.out.println("Foo Started: " + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bar(msg);
}
synchronized void bar(String msg) {
System.out.println("bar started: " + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
foo(msg);
}
}
class ThreadObj1 extends Thread {
SyncObj so;
public ThreadObj1(SyncObj so) {
this.so = so;
}
#Override
public void run() {
so.bar("TO1");
}
}
class ThreadObj extends Thread {
SyncObj so;
public ThreadObj(SyncObj so) {
this.so = so;
}
#Override
public void run() {
so.foo("TO");
}
}
You can see the following output:
Foo Started: TO
bar started: TO
Foo Started: TO
bar started: TO
Foo Started: TO
bar started: TO
You can consider 'synchronized' to mean lock(this), where 'this' is a SyncObj instance. Therefore there is exactly one lock, and it's impossible to obtain a deadlock.

While others have already pointed out that a deadlock only occurs when you have two resources where each thread locks one and then waits for the other, I think there is one crucial point missing, where your entire confusion probably comes from:
synchronize on a method does not create a lock for that particular method, it creates a lock for the entire object it belongs to. Thus your class is equivalent to this:
class SyncObj {
void foo() {
synchronized(this) {
System.out.println("Foo Started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bar();
}
}
void bar() {
synchronized(this) {
System.out.println("bar started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
foo();
}
}
}
Now it should be much more clear, why you don't get a deadlock.
You can easily modify your code to be prone to a deadlock by introducing two resources, one for each method:
class SyncObj {
private Object foolock = new Object();
private Object barlock = new Object();
void foo() {
synchronized(foolock) {
System.out.println("Foo Started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bar();
}
}
void bar() {
synchronized(barlock) {
System.out.println("bar started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
foo();
}
}
}

Deadlock is not possible using a single instance because no two threads of the same object can access more than one synchronised method.
In the above example if thread 1 is accessing foo method. Thread 2 cannot access either foo nor bar method. Untill thread 1 finishes it task

Related

Implementing a "fence" object in Java without using threads

I have been assigned an exercise from my uni professor that goes as follow:
"A fence object is an object that has a collection of objects, and can wait on any of those objects is signaled. There is an add(Object) method, which adds an object to the collection. There is also an await() method: this allows to wait on any object of the collection to be signaled. Whenever the add(Object) method is called while the await() method is active, the argument of the add is put in queue. Write the source code using the following interface: ".
public interface Fence {
public void await() throws InterruptedException;
public void add(Object o);
}
So, only when the same number of notify() and objects in queue (aka the number of add(Object) ) are called, the await() terminates and the object in the queue are finally added to the collection. <- this is something I got wrong and realized after writing my code
I did make the implementation as follow:
import java.util.LinkedList;
public class FenceImpl2 implements Fence{
private LinkedList<Object> collection;
private Object mutex; ;
static boolean iswaiting = false;
public FenceImpl2() {
this.collection = new LinkedList<Object>();
this.mutex = new Object();
}
#Override
public void await() throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
synchronized(mutex) {
mutex.wait();
iswaiting = true;
}
} catch (InterruptedException e) {
e.printStackTrace();
}}});
t1.start();
}
#Override
public void add(Object o) {
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
synchronized(mutex){
if(iswaiting == true) {
try {
mutex.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else {
collection.add(o);
}
}}});
t2.start();
}
public Object getList() throws InterruptedException {
synchronized(mutex){
System.out.println("Collection list: \n");
for(Object o : collection) {
System.out.println(o);
Thread.sleep(1000);
}
System.out.println("------- \n");
return collection;
}
}
public void notification() {
Thread thread = new Thread(()->{
synchronized(mutex){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mutex.notify();
}
});
thread.start();
}
public static void main(String[] args) throws InterruptedException {
FenceImpl2 f = new FenceImpl2();
Object o1 = 1;
Object o2 = 2;
Object o3 = 3;
Object o4 = 70;
f.add(o1);
System.out.println("Add 1");
f.add(o2);
System.out.println("Add 2");
f.add(o3);
System.out.println("Add 3");
f.await();
System.out.println("Await active ");
f.add(o4);
System.out.println("Aggiungo 70 - Shouldn't appear. Forced in queue");
f.getList();
f.notification();
System.out.println("Notify() sent - 70 should now appear in the collection");
f.getList();
}
}
After submitting it to my professor I have been told two things:
The synchronization is not correct: the await "unlocks" after the first notify and that shouldn't happen because it doesn't wait for the other (if any) objects that are in queue to be notified.
^Let me say I know how to fix that easily but
Although it's a minor mistake, the methods await, add and notification SHOULD NOT be done using asynchronous dedicated threads.
Here it finally comes my problem. How am I supposed to use wait() on a lock object and then notify() if I am not using dedicated threads?
I tried removing the threads but obviously as soon as I'm calling mutex.wait() the program locks and the code right after that calls the notification method is not reached.
Why did my professor tell me using threads is wrong?
How can I use a wait() and then call a notify() in two separate methods without having the program lock?
Here's an example of what I mean:
public class testw {
private Object mutex;
boolean condition = false;
public testw() {
this.mutex = new Object();
}
public void startWait() {
synchronized(mutex) {
try {
Thread.sleep(1000);
condition = true;
while(condition == true) {
System.out.println("Waiting!");
mutex.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void sendNotify() {
synchronized(mutex) {
try {
Thread.sleep(3000);
System.out.println("Notify!, not waiting anymore");
condition = false;
mutex.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
testw t = new testw();
t.startWait();
t.sendNotify();
}
Without using threads, when I startWait() is called the main thread goes in wait, but there's no way that sendNotify() to be called and the programs freezes. Is there a way to do this without using threads or am I missing something?
Thank you very much.
I have been told...Although it's a minor mistake, the methods await, add and notification SHOULD NOT be done using asynchronous dedicated threads.
The whole point of a method named await() is that it should not return until the event that the caller wants to wait for has happened.
Your await() method doesn't wait. It creates a new thread and then it immediately returns. The new thread waits for something, but after that it just dies without doing anything useful. The new thread might as well not exist at all.
Your add(o) method doesn't make a whole lot of sense either. I'm not even sure what you were trying to do with it, but I think you need to take a step back, and try to explain to the duck why you thought that either of those two methods should create a new thread.
How am I supposed to use wait() on a lock object and then notify() if I am not using dedicated threads?
The Oracle "Guarded Blocks" tutorial is an oldie but a goodie. If you work through it to the end, it should give you a pretty clear idea of how and why and when to use wait() and notify().
https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

Method synchronized , but code produces random result due to non-serialized thread behaviour

Here is my code:
public class ThreadDemo {
public static void main(String args[]) throws Exception {
Printer[] printers = new Printer[5];
printers[0] = new Printer("#base");
printers[1] = new Printer("#try");
printers[2] = new Printer("!test");
printers[3] = new Printer("^hello");
printers[4] = new Printer("*world");
for (Printer x : printers) {
x.start();
}
try {
for (Printer y : printers) {
y.join();
}
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
class Printer extends Thread {
public Printer(String name) {
super(name);
}
public void run() {
print();
}
public synchronized void print() {
for (int i = 0; i < 10; i++) {
System.out.print(getName().charAt(0));
try {
sleep(100);
} catch (InterruptedException e) {
System.out.println(e + " occured");
}
}
}
}
It results in
#^!#**#^!#*##!^#*#^!#^!*#^*#!##!#*^##^!*!#^#*##*^!
My expectation is that all symbols would be serialized as #####^^^^^ based on which thread starts first.
Calling sleep() would let other threads to proceed until sleeptime of current thread , but i guess that should not be the case with synchronized method.
The synchronised doesn't come into play here.
That keyword makes sure that you can't invoke the same method on the same object in parallel.
You are invoking it on different objects, therefore the result would be the same even without the keyword in place!
( I rather assume that the result you see is in fact caused by using println() here. That is a "really slow" operation that introduces "de facto" synchronisation when used by threads that are super-quick doing all their other work. I am trying to find some additional information about that, but that might take some more time )
The issue with your code or I would say your expectation is that the method print is synchronized at the object level and you are creating new thread objects, starting the thread and calling this method.
So in this case, each method is synchronized on each individual thread object. To achieve the behavior you expect, we can make the print method static and see the behavior change. You will get the expected result because then, the method print is synchronized on a single instance of Printer class lock. So even if different threads instance are calling this method, because there is a single lock for class, thread execution happens sequentially.
public static synchronized void print() {
for (int i = 0; i < 10; i++) {
System.out.print(Thread.currentThread().getName().charAt(0));
try {
sleep(100);
} catch (InterruptedException e) {
System.out.println(e + " occured");
}
}
}
#SolomonSlow - So it has to be corrected as 'No Synchronized methods' can be called on the same object at same time ?
There is only one thing you will ever need to know about a synchronized instance method. You need to know that this...
synchronized void Foobar() { ... }
...Is just a shortcut way of writing a synchronized block.
void Foobar() {
synchronized (this) {
...
}
}
Both of those method declarations do exactly the same thing. So, everything you know or learn about how synchronized blocks behave can be applied to synchronized methods too.
The most important thing to know about synchronized blocks is, "No two threads can ever be synchronized on the same object at the same time." If you understand that, and if you know how a synchronized method is just a shortcut for a synchronized block, then you can answer your own question.

java multi threading..thread communicating each other

My Question is related to the Working of two thread at a time,suppose one thread write a file and release the resource to another thread for reading the same file and vice versa.But the communication is not happening properly. here is the code snippet
Thread 1
public void run() {
for(int i=1;i<10;i++) {
System.out.println(i+"i");
System.out.println("writing the file");
try {
synchronized (new A()) {
wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Thread 2
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(int j=1;j<10;j++) {
System.out.println(j+"j");
System.out.println("reading the file");
synchronized (new B()) {
notifyAll();
}
}
synchronization happens on a particular monitor object.
In your code you create new monitors for each synchronization block, with the new operator.
So you will never lock the access to this fragment of code because no other monitor can be taken by another thread.
This is the classic "producer consumer/reader writer" concurrency problem. There are several ways you can go about this - Some being slightly outdated however easier to understand for a beginner like yourself.
In order for 2 or more threads to be dependent on each other starting or finishing, there must be a concept of a shared object or variable which can be changed by each thread, to signal the other threads that the current one is finished. It is important that only one thread is changing the shared object at any one time (Also known as the critical section). In this case, you could use some Java 8 concurrency features to synchronise these 2 threads. Heres a simple example below using some Java 8 Concurrency syntax, namely the ReadWriteLock, which has been created especially for this use case.
public class ReaderWriterProblem {
private ReentrantReadWriteLock theLock = new ReentrantReadWriteLock(true);
public static void main(String[] args) {
ReaderWriterProblem rwProblem = new ReaderWriterProblem();
Reader reader1 = new Reader(theLock);
Writer writer1 = new Writer(theLock);
new Thread(reader1).start();
new Thread(writer1).start();
}
private class Reader implements Runnable {
private ReentrantReadWriteLock theLock;
public Reader(ReentrantReadWriteLock theLock) {
this.theLock = theLock;
}
public void run() {
try {
theLock.readLock().lock();
System.out.println("Currently Reading!");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
} finally {
theLock.readLock().unlock();
}
}
}
private class Writer implements Runnable {
private ReentrantReadWriteLock theLock;
public Writer(ReentrantReadWriteLock theLock) {
this.theLock = theLock
}
public void run() {
try {
theLock.writeLock().lock();
System.out.println("Currently Writing!");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
} finally {
theLock.writeLock().unlock();
}
}
}
}
This is a very basic example but the ReadWriteLock actually comes with built in support for one writer at any time and many readers. So when a thread holds the write Lock, no other thread can write at the same time, however several threads can hold the read lock at one time.
Other potential solutions to this problem include semaphores and busy wait, which are worth having a look at online.
SHORT ANSWER to why your question was wrong - You need to synchronise shared objects and variables, not the instances of classes that are executing the concurrent statements. Hope this helps you understand a little more. Notice how the lock is shared between the reader and writer.

Is there a way in Java to call a method on an already-running object in a separate thread?

The idea is, an object already is executing some method and perhaps you want to invoke a different method that will only begin to execute when the first method is finished. The only way that occurs to me is to pass a message via a member that is visible to the thread and the object will check the message, executing the appropriate method and perhaps depositing the results of that method in a place where the first thread can see this. Perhaps there is a more elegant approach?
EDIT: I am reading about the asynchronous annotation or Spring's asynch annotation and it appears that this might be what I need...
Add synchronized to both methods.
Try running the following with and without the synchronized keyword.
public class SynchronizedMethods {
public synchronized void longRunningMethodA() {
System.out.println("Method A - Start");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
}
System.out.println("Method A - End");
}
public synchronized void longRunningMethodB() {
System.out.println("Method B - Start");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
}
System.out.println("Method B - End");
}
public static void main(String[] args) {
final SynchronizedMethods object = new SynchronizedMethods();
new Thread() {public void run() {
object.longRunningMethodB();
}}.start();
object.longRunningMethodA();
}
}
Happy coding!

IllegalMonitorException using Semaphore and Monitor in Java

I have a project for my "Operating Systems". I need to write 2 programs with java...
write a program that produce Water with 2 method Oxygen and Hydrogen.
method Oxygen produce one Oxygen and method Hydrogen produce one hydrogen. when 2 Hydrogen and one Oxygen was existed H2O created. I must write this with with Semaphores and threads.
Write the above problem with Monitors and Sychronize.
I've writed some code for this but it gives illegal monitor exeption...
please help me to correct it...
This is my code:
// class for implement Thread for oxygen
public class Thread_O implements Runnable {
public void run() {
thread t = new thread();
try {
t.oxygen();
} catch (InterruptedException ex) {
Logger logger = Logger.getLogger(Thread_O.class.getName());
logger.log(Level.SEVERE, null, ex);
}
}
}
// class for implement Thread for Hydrogen
public class Thread_H implements Runnable {
public void run() {
thread t = new thread();
try {
t.Hydrogen();
} catch (InterruptedException ex) {
Logger logger = Logger.getLogger(Thread_H.class.getName());
logger.log(Level.SEVERE, null, ex);
}
}
}
//class for method Oxygen and Hydrogen
public class thread {
Semaphore O = new Semaphore(0, true);
Semaphore H = new Semaphore(0, true);
Semaphore H2O = new Semaphore(0, true);
Semaphore safe = new Semaphore(1, true);
public void oxygen() throws InterruptedException {
safe.wait();
H.wait();
H.wait();
H2O.release();
H2O.release();
Safe.release();
// System.out.println("O2...!");
}
public void Hydrogen() throws InterruptedException {
H.release();
H2O.wait();
// System.out.println("H2...!");
}
}
and in action of Oxygen Button:
Thread th = new Thread(new Thread_O());
th.start();
I'm not going to decode your homework for you, but an IllegalMonitorException is thrown when you're trying to wait() on an object without being synchronized. So to wait for an object called list:
synchronized (list) {
try {
list.wait();
} catch(Throwable t) {
t.printStackTrace();
}
}
You have to understand how the producer/consumer mechanism work.
Here you'll have one consumer thread and two producers.
First you'll have one thread producing oxygen, and other producing hydrogen.
Then, those molecules should be places "somewhere" ok? That "something" is the thing that has to be monitored and synchronized.
So it should go something like this:
class Water {
char [] waterMolecule = new char[3]; // <-- synchronize access to this
char hydrogen(){
return 'H';
}
char oxygen() {
return 'O';
}
void produce() {
Thread t = new Thread( new Runnable() {
synchronize( waterMolecule ) {
waterMolecule[0] = hydrogen();
}
}):
.... produce the others
}
void consume() {
synchronize watermolecule
if waterMolecule is complete
create water and clean out the molecule.
}
}
That's the basic idea.
Just bear in mind that you won't be able to produce another particle of oxigen until the previous one has been consumed.
Also you must always call wait in a while loop
Here's how that wait/synchronize should be coded.
Here's a number of producer/consumer samples.
Although your homework is already due, I'd like to propose CyclicBarrier as the best solution for this scenario.
It allows some kind of rendezvous for the different threads (here: your molecule producers) and triggers the execution of an additional runnable on completition (here: creation of h20).

Categories

Resources