Why is this code deadlocking? [closed] - java

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I need some help concerning deadlocks. I just do not understand why my code is deadlocking here.
I tried different scenarios.
However I still can't find why and where is the problem. Normally it should work
and I don't find where the deadlock is between debuter and termine.
public class Interblocking {
protected object obj = object();
private boolean condition = true;
public synchronized void debuter() {
synchronized(obj) {
while (!condition) {
try {
obj.wait();
} catch (InterruptedExeption ie) {}
}
condition = false;
}
}
public synchronized void terminer() {
synchronized(obj) {
condition = true;
obj.notifyAll();
}
}
}

Edit (new answer)
Method wait() doesn't release all locks of current Thread.
So when A thread invokes debuter it releases only obj lock but holds this lock so other threads can't invoke terminer method.
Here is example:
class WaitReleaseTest implements Runnable {
Object lockA, lockB;
public WaitReleaseTest(Object lockA, Object lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
public void run() {
System.out.println(Thread.currentThread().getName()
+ " attempting to acquire lockA");
synchronized (lockA) {
System.out.println(Thread.currentThread().getName()
+ " attempting to acquire lockB");
synchronized (lockB) {
System.out.println(Thread.currentThread().getName()
+ " holds lockA = " + Thread.holdsLock(lockA));
System.out.println(Thread.currentThread().getName()
+ " holds lockB = " + Thread.holdsLock(lockB));
try {
lockB.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object o1=new Object();
Object o2=new Object();
new Thread(new WaitReleaseTest(o1,o2)).start();
TimeUnit.MILLISECONDS.sleep(500);
new Thread(new WaitReleaseTest(o1,o2)).start();
}
}
output
Thread-0 attempting to acquire lockA
Thread-0 attempting to acquire lockB
Thread-0 holds lockA = true
Thread-0 holds lockB = true
Thread-1 attempting to acquire lockA
... now it waits

The code does not contain deadlock conditions. Deadlocks occur when there are cycles in the graph of resources. You have only one resource (obj) so the resource graph consists of single node and cannot contain cycles.
While debuter may wait forcondition, terminer never waits for long time.

I guess your code is total different from what your code is able to do.
You probably want a thread entering debuter to wait until condition is to true;
The basic problem are the synchronized keyword on the method. They assure that only thread is in any method of your instance of Interblocking
Remove synchronized on the methods.
The next problem is condition. It is undefined how may thread becomes released after called terminer
You run into a dead lock on the second call to debuter because condition is false after the first call to debuter.
And there is no way to execute terminer because there is a thread in debuter blocking
Using multiple levels of blocking objects (in this case object and this) is always suspicious to cause a dead lock.

Related

Can a java thread waiting with wait() ,notify itself?

I came across the following e example to implement custom suspend and wait from some website.
// Suspending and resuming a thread the modern way.
class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for (int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
...................
I am more concerned about the ob1.mysuspend() and ob1.myresume() calls. When my suspend is called then ob1 will be placed into the blocking queue associated with the runnable object it is using. When ob1 calls myresume, then how does it work as ob1 is already in waiting queue for the same object, can the waiting object enters another synchronised method and then signals notify to itself?How does this work?What am I missing?
The thread is written so that while an instance of NewThread is running, another thread can call mysuspend to suspend that running thread. Again, a thread other than the suspended thread calls myresume to resume the suspended thread.
There also appears to be a data race because mysuspend writes to suspendFlag without any synchronization. That means, the thread that needs to be suspended may not see that write immediately. mysuspend must be declared synchronized, or suspendFlag must be volatile.
This code is flat out broken.
Straight up broken: JMM violation
The mysuspend method (which should be named mySuspend, by the way) updates a field that is then read from another thread, and isn't synchronized. This is an error - and a really nasty one because you cannot reliably test that it is an error. The Java Memory Model (JMM) states that any write to a field may be observable or not, at the discretion of the JVM implementation, unless a so-called Happens-Before/Happens-After relationship is established (there are many ways to do it; usually you do so via synchronized, volatile, or some other concurrency tool built on these primitives, such as the latches and queues in the java.util.concurrent package).
You do not establish such a relationship here, meaning, that suspendFlag = true results in a schroedingers cat variable: The other thread that reads this field may read true or false, the JVM gets to decide what you see. Hence: A bug, and, untestable. bad. Any field that is read/written to by multiple threads needs to be written extremely carefully.
Mark that method synchronized, that's a good first step.
Wait and Notify
You've got it flipped around: You must in fact hold the synchronized lock on x when you invoke wait on x (here, x is this).
To call x.wait() (you are calling this.wait(), effectively), you must first be in a synchronized(x) block. Once the wait 'goes through', the code releases the lock (other synchronized(x) blocks can run). To invoke x.notify() you must also hold that lock.
wait does not return until the lock is re-established.
In other words:
public void foo() {
wait();
}
will fail at runtime. Try it. Guaranteed exception. In the mean time, this:
public void foo() {
synchronized (this) {
// code before wait
wait();
// code after wait
}
}
is executed as if it is written like this:
public void foo() {
synchronized (this) {
// code before wait
release_lock(this);
this.wait();
acquire_lock(this);
// code after wait
}
}
Where acquire_lock is guaranteed to actually take a while (because by definition whatever invoked notify() to wake you up is currently holding it! So wait is always a two-hit thing: You need to be both notified AND the lock needs to be reacquired before your code will continue). Except, of course, acquire_lock and release_lock don't exist, and unlike this hypothetical code, wait() is more atomic than that.

Significance of use of keyword synchronized in the following code

I was reading multi threading in Java from the book Java The Complete Reference by Herbert Schildt. I came across following code [Pg. 252, 7th ed.] that explained the usage of wait() and notify() to suspend and resume threads in modern Java. My question is regarding the significance of the keyword synchronization at two places in following code (in run() method of class NewThread):
// Suspending and resuming a thread the modern way.
class NewThread implements Runnable {
String name;
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
suspendFlag = false;
t.start();
}
// This is the entry point for thread.
public void run() {
try {
for (int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized (this) { //First doubt here
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() { //Second doubt here
suspendFlag = false;
notify();
}
}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
Thread.sleep(1000);
ob1.myresume();
ob2.mysuspend();
Thread.sleep(1000);
ob2.myresume();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
//some code
}
My doubt here: I know about the use of keyword synchronization i.e. allowing only one thread to enter a synchronized method on the same object but here we have two threads running on two different objects. So what is the significance of both synchronization keywords used in above code.
I tried running the above code by removing the synchronized keyword at each place differently and simultaneously. I am getting the same error: java.lang.IllegalMonitorStateException: current thread is not owner different number of times and at different line numbers depending upon if I remove both or only one (and which one) synchronization keyword. I looked for the above error and found an explanation for it here but still couldn't connect the answer to my doubt.
The problem that synchronized solves is, it allows the two threads to have a consistent view of the shared suspendFlag variable.
In some real program, a thread might set other shared variables before setting susependFlag=false. If synchronized was not used, then the waiting thread could wake up, and see suspendFlag==false, but not see the other variables set. Or worse, it could see some of them set, but not others.
Without synchronization, Java does not guarantee that different threads will see variables updated in the same order.
I am getting the same error: java.lang.IllegalMonitorStateException: current thread is not owner.
The Java library is trying to help you by forcing you to use synchronized before it will allow you to use wait() and notify(). The rule is simple: You can only call o.wait() or o.notify() or o.notifyAll() from code that is inside a synchronized(o) block. If you break that rule, then the library throws the exception.
When your code calls o.wait() the wait() call temporarily unlocks the monitor lock so that the other thread will be able to synchronize on o and call o.notify(). The o.wait() call is guaranteed to re-lock o before it returns.

Is it possible that 2 synchronized methods of an object are accessible by 2 threads at the same time?

This question was asked to me in an interview. Before I had told him this,
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
Consider the snippet:
Q1:
public class Q1 {
int n;
boolean valueSet = false;
synchronized int get() {
while (!valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while (valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
Producer1:
public class Producer1 implements Runnable {
Q1 q;
Producer1(Q1 q) {
this.q = q;
new Thread(this, "Producer").start();
}
#Override
public void run() {
int i = 0;
while (true) {
q.put(i++);
}
}
}
Consumer1
public class Consumer1 implements Runnable {
Q1 q;
Consumer1(Q1 q) {
this.q = q;
new Thread(this, "Consumer").start();
}
#Override
public void run() {
while (true) {
q.get();
}
}
}
PC1:
public class PC1 {
public static void main(String args[]) {
Q1 q = new Q1();
new Producer1(q);
new Consumer1(q);
System.out.println("Press Control-C to stop.");
}
}
So, he asked as soon as you have created this thread new Producer1(q), then according to you, the synchronized int get() method must have been locked by the same thread, i.e, by new Producer1(q) when it accessed synchronized int put(). I said yes.
But I checked in eclipse, get is callable by new Consumer1(q). The program works perfect.
Where am I going wrong?
O/P:
The call to wait() will release the monitor for the time waiting.
That's what is documented for Object.wait():
The current thread must own this object's monitor. The thread
releases ownership of this monitor and waits until another thread
notifies threads waiting on this object's monitor to wake up
either through a call to the notify method or the
notifyAll method. The thread then waits until it can
re-obtain ownership of the monitor and resumes execution.
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
What you forgot to add here is "except if the lock is released".
...and it is the case in your example, when calling wait.
The documentation specify :
The thread releases ownership of this monitor and waits until another
thread notifies threads waiting on this object's monitor to wake up
either through a call to the notify method or the notifyAll method.
Since the lock is released, you step in the other method (and the condition is true because the boolean was modified). Once in the other method, you release the lock again, then call notify and you wake up the old thread which terminates (re-modify boolean to pass the condition in other method, and notify). That way you step between both methods ad-infinitum.
wait() and notify() is acts as a signal between threads, to control the threads to do or to not do the stuff.
The program works perfect because here 2 threads (Producer, Consumer) which fight for the one lock (monitor). When Consumer aquires the lock (Q1 object) then Producer is waiting for the lock. When Consumer finishes his work it release the lock. Consumer releases the lock also when wait() method has been called, because wait() sets thread to Waiting state with lock release. It's time for Producer to aquire the lock and does his work. When Producer thread notify() calls then Consumer continue his work (when aquired the lock). The same is right for Producer.
Resume: Q1 object is a lock for all threads. If it aquired someone then others are blocked and the answer is - it not possible to get an access at the same time to the get(), put() methods more then 2 threads.
I think that the question is ambiguous. (E.g., what does "accessible" mean?)
IMO, a good interview question should not have a right answer and a wrong answer. A good interview question should be a conversation starter, that gives you an opportunity to show how much you know about the subject.
When I am asking the interview questions, I like a candidate who can see through the question, and get down to the underlying mechanism. E.g.,
What the JLS guarantees is that no two threads can be _synchronized_
on the same instance at the same time...
Then we could explore questions like, how could two threads enter the same synchronized method at the same time? (e.g., synchronized on different instances), how could two threads be in the same synchronized method for the same instance at the same time (one of them could be in a wait() call), ...
A thread can not access a synchronized block of code unless it has aquired a lock on the object that guards the block. In your case, the synchronized keyword uses the lock of the object in which it has been declared. So as long as a thread is executing get(), no other thread can execute the put().
If you apply this, when put() sets the value, it notifies consumer which accepts the value. The code should work even after you have removed the wait() and notify() calls from both get and put methods

Synchronizaton Object Lock Confusion

I am studying K&B threads chapter. I was reading about synchronization. Here is an example from
K&B.
public class AccountDanger implements Runnable {
private Account account = new Account();
public void run() {
for(int x =0 ; x < 5 ; x++){
makeWithdrawl(10);
if(account.getBalance() < 0 ){
System.out.println("account is overdrawn");
}
}
}
public static void main(String[] args){
AccountDanger accountDanger = new AccountDanger();
Thread one = new Thread(accountDanger);
Thread two = new Thread(accountDanger);
one.setName("Fred");
two.setName("Lucy");
one.start();
two.start();
}
private synchronized void makeWithdrawl(int amt){
if(account.getBalance() >= amt){
System.out.println(Thread.currentThread().getName() + " is going to withdraw");
try{
Thread.sleep(500);
}
catch(InterruptedException e) {
e.printStackTrace();
}
account.withdraw(amt);
System.out.println(Thread.currentThread().getName() + " completes the withdrawl");
}
else{
System.out.println("Not enough in account for " + Thread.currentThread().getName() + " to withdraw " +
account.getBalance());
}
}
}
K&B talks about synchronized methods and synchronized blocks. Here is referring paragraph from K&B.
When a method is executing code from within synchronized block, code
is said to be executing in a synchronized context. When you
synchronize a method, the object used to invoke the method is the
object whose lock must be acquired. But when we synchronize block of
code, you must specify which object's lock you want to use as a lock.
So in this example, will the lock be acquired on AccountDanger instance or Account object?
I think so it should be AccountDanger. Am i perceiving correct? If it is AccountDanger object,
and one thread has got the lock of AccountDanger, will any other thread be able to call non-synchronized methods?
So in this example, will the lock be acquired on AccountDanger
instance or Account object?
Yes. One trick I've seen used a lot is to synchronize on this when you have only a small block of code that actually needs to be synchronized. For example:
int balance = -1;
synchronized(this) {
balance = account.getBalance();
account.withdraw(amt);
}
//IO, etc. after that.
In general this speeds things up.
private synchronized void makeWithdrawl(int amt){
//is implicitly acquiring lock on this object (AccountDanger object)
}
So in the example the first thread to call this method will enter the synchronized block acquiring this object monitor and holds it and no other thread except the first thread itself can acquire the monitor lock again on this. All the other threads that call this method will block until the first thread releases the lock and frees the monitor.
Note: Locks used for synchronized blocks are Re-entrant in nature.

analysing the difference betweeen synchronize and lock [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I am a newbie to the world of Threads and I am going through threads to latest util package reentrant lock mechanism, I was going through the basis differences between synchronize mechanism and the newly added lock mechanism , as in the article these were the differences..
Another significant difference between ReentrantLock and synchronized keyword is fairness. synchronized keyword doesn't support fairness. Any thread can acquire lock once released, no preference can be specified, on the other hand you can make ReentrantLock fair by specifying fairness property, while creating instance of ReentrantLock. Fairness property provides lock to longest waiting thread, in case of contention.Please if you could provide a small program which proves this point sp that I can grasp more
main difference between synchronized and ReentrantLock is ability to trying for lock interruptibly, and with timeout. Thread doesn't need to block infinitely, which was the case with synchronized, Please if you could provide a small program which proves this point sp that I can grasp more
One more worth noting difference between ReentrantLock and synchronized keyword in Java is, ability to interrupt Thread while waiting for Lock. In case of synchronized keyword, a thread can be blocked waiting for lock, for an indefinite period of time and there was no way to control that. ReentrantLock provides a method called lockInterruptibly(), which can be used to interrupt thread when it is waiting for lock. Similarly tryLock() with timeout can be used to timeout if lock is not available in certain time period.Please if you could provide a small program which proves this point sp that I can grasp more
Guys could you please provide a small program which shows all these above three points
I have tried this program , please advise what changes need to be done in it to prove above 3 points..
public class ReentrantLockHowto {
private final ReentrantLock lock = new ReentrantLock();
private int count = 0;
//Locking using Lock and ReentrantLock
public int getCount() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " gets Count: " + count);
return count++;
} finally {
lock.unlock();
}
}
//Implicit locking using synchronized keyword
public int getCountTwo() {
return count++;
}
public static void main(String args[]) {
final ThreadTest counter = new ThreadTest();
Thread t1 = new Thread() {
#Override
public void run() {
while (counter.getCount() < 6) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace(); }
}
}
};
Thread t2 = new Thread() {
#Override
public void run() {
while (counter.getCount() < 6) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
};
t1.start();
t2.start();
}
}
Output:
Thread-0 gets Count: 0
Thread-1 gets Count: 1
Thread-1 gets Count: 2
Thread-0 gets Count: 3
Thread-1 gets Count: 4
Thread-0 gets Count: 5
Thread-0 gets Count: 6
Thread-1 gets Count: 7

Categories

Resources