I am trying to implementing deadlock condition but somehow I am not able to get it working. Both the threads Thread1 and Thread2 are entering in the run function but only one of them enters in Sub/Sum depending on who entered run first. Example : if Thread2 entered run first the it will call sub() and Thread1 never calls sum(). I have also added sleep time so that Thread2 sleeps before calling sum() and Thread1 gets enough time to enter Sum() but Thread1 never enters.
public class ExploringThreads {
public static void main(String[] args) {
// TODO Auto-generated method stub
threadexample a1 = new threadexample();
Thread t1 = new Thread(a1, "Thread1");
Thread t2 = new Thread(a1,"Thread2");
t1.start();
t2.start();
}
}
class threadexample implements Runnable{
public int a = 10;
public void run(){
if(Thread.currentThread().getName().equals("Thread1"))
sum();
else if(Thread.currentThread().getName().equals("Thread2"))
sub();
}
public synchronized void sum()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sum");
sub();
}
public synchronized void sub()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sub");
sum();
}
}
If you really want to create an artificial dead lock, try this:
Thread1 and Thread2 are two threads that want to access the same file.
Thread1 starts, asks for a lock on File1.docx and sleeps for 2 minutes.
Thread2 starts, and makes an exclusive lock on File2.docx and now wants to access File1.docx.
Thread1 wakes up and now wants to access File2.docx which is held by Thread2
Now, this is a circular wait condition
Simple ? =)
This is not how you get a deadlock. Actually this code seems pretty safe :-) Only one thread enters sum/sub at a time because you are using synchronized which synchronizes on "this". There is only one "this" so both threads try to acquire the same lock.
Deadlock occurs, for instance, when Thread1 has one lock, Thread2 has second lock and then Thread1 would like to acquire Thread2's lock while still holding it's lock and Thread2 would like to acquire Thread1's lock while still holding it's lock.
What you could do is:
a) add 2 objects for locking in "threadexample" class (btw classes by convention should start with uppercase):
private final Object sumLock = new Object();
private final Object subLock = new Object();
b) drop the "synchronized" keyword in both sum/sub methods and instead use the synchronized() {} block in each of them. Sum would be synchronized(sumLock) { /* sum's body goes here / } and sub would be synchronized(subLock) { / sub's body goes here */}.
In this case Thread1 would go into sum(), acquire the sumLock and wait. Thread2 would go into sub(), acquire the subLock() and wait. Thread1 would wake up, go into sub() and try to acquire subLock but it's being held by Thread2 so it wait's until Thread2 releases it. In that time Thread2 wakes up, goes into sum() and tries to acquire sumLock which is held by Thread1 so Thread2 waits for Thread1 to release it.
Neither thread will go forward as each one of them is waiting for the other - you have a deadlock.
#Edit: yes you have only 1 instance of "threadexample" and both Thread1 and Thread2 are fighting for the lock but when one of them acquires the lock it will release it after executing sum/sub or sub/sum. For instance let's say Thread1 is first and starts executing sum(). It has the lock. In that case Thread2 will not go into sub() as it is protected by the same lock as Thread1. Thread1 will do sum(), then sub() and then it will release the lock --> Thread2 will go into sub() etc.
This is a working example of 'Deadlock in Action'. Basically what you need to do (and how that usually happens in real world) is that object are locked in opposite order: a first, b second in one thread and b first, a second in another:
package stackoverflow;
public class Deadlock {
final static String a = new String("A");
final static String b = new String("B");
public static void main(String[] args) {
final Thread abLock = new Thread() {
#Override
public void run() {
lock(a, b);
}
};
final Thread baLock = new Thread() {
#Override
public void run() {
lock(b, a);
}
};
abLock.start();
baLock.start();
}
static void lock(String first, String second) {
synchronized (first) {
System.out.println(first);
sleep();
synchronized (second) {
System.out.println(second);
}
}
}
static void sleep() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Related
This program works fine by printing alternate numbers via different threads but when all the numbers from 0-9 are printed Why does this program not stop? I have to manually stop my application.
public class EvenOddPrinter implements Runnable{
private AtomicInteger num = new AtomicInteger(0);
private Object lock = new Object();
#Override
public void run() {
synchronized (lock){
while (num.get()<10){
System.out.println(num.getAndAdd(1) + " - "+Thread.currentThread().getName());
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Executor {
public static void main(String[] args) throws InterruptedException {
EvenOddPrinter eop = new EvenOddPrinter();
Thread t1 = new Thread(eop);
Thread t2 = new Thread(eop);
t1.start();
t2.start();
}
}
that's because in the last Thread getting stuck at wait. notifyAll will notify all waiting thread if any there and release lock.
while (num.get()<10){
// existing implementation
}
lock.notifyAll();
The second thread t2 keeps waiting on the lock in the end, and t1 doesnt do the notify() anymore because the while condition becomes false. You must put a lock.notify(); statement outside of the while loop.
As soon as the number reached 8 the first thread calls notify() and goes to wait(). Second thread then makes the number 9 and calls notify() and goes to wait(). First thread is then not able to go inside the loop as specified in the condition, therefore, it exits the synchronized and block and finishes but second thread is still waiting. There has to be a mechanism to notifyAll() as soon as one of the threads exits the synchronized block which is exactly what I did.
#Override
public void run() {
synchronized (lock){
while (num.get()<10){
System.out.println(num.getAndAdd(1) + " - "+Thread.currentThread().getName());
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notifyAll();
}
Also, lock is pointless when I am using AtomicInteger (or the other way round).
I have the following kind of code:
synchronized block1 {
//only one thread in the block
}
{lot of code where synchronization not necessary}
synchronized block2 {
//only one thread in the block.
//All the threads that executed block1 before this thread should have already executed this block.
}
Each thread first executes block1, non synchronized block, and block2 in that same order.
If thread T1 executes block1 before thread T2, then T1 should execute block2 before T2. There are more than two threads.
Is there a way to achieve this in java?
As I understand Critical Section #2 MUST be executed in the same order as Critical Section #1
If thread T1 executes block1 before thread T2, then T1 should execute block2 before T2. There are more than two threads.
Then a Queue might be used to ensure the order of execution.
private Object lock = new Object();
private Queue<Thread> threadQueue = new ArrayDeque<>();
// https://stackoverflow.com/questions/32353283/synchronization-threads-execute-two-critical-sections-in-same-order
public void executeCriticalSectionsInOrder() throws InterruptedException {
// Critical Section #1
synchronized (lock){
// synchronized code #1
// Add self to queue
threadQueue.add(Thread.currentThread());
}
// {lot of code where synchronization not necessary}
// Critical Section #2
synchronized (lock) {
//All the threads that executed block1 before this thread should have already executed this block.
// Wait turn
Thread t = threadQueue.element(); // Do not remove until it is self
while (t != Thread.currentThread()) {
lock.wait();
// After sleep try again
t = threadQueue.element();
}
// Verified own turn. Update status
threadQueue.remove();
// synchronized code #2
lock.notifyAll(); // Awake any waiting thread after exiting section.
}
However If one thread dies/exits without removing itself from the queue, then following threads will be blocked indefinetely. Maybe add a finally block to do the housekeeping?
Note: In Nicholas Robinson's answer a position order was suggested instead of a queue, which seems slightly more efficient.
This basically creates a queue that threads will wait in until their number comes up. [UPDATED]
private AtomicInteger place = new AtomicInteger(0);
private AtomicInteger currentPlaceInQueue = new AtomicInteger(0);
private ReentrantLock lock = new ReentrantLock();
private Condition notNext = lock.newCondition();
public void method() {
ThreadLocal position = new ThreadLocal();
synchronized(this) {
//Your code
position.set(place.getAndIncrement());
}
// More code
lock.lock();
while ((int) currentPlaceInQueue.get() != position.get()) {
notNext.await();
}
// More code
lock.unlock();
currentPlaceInQueue.getAndIncrement();
notNext.notifyAll();
}
The synchronized blocks in your example are a red herring. Your problem is, you have N threads, and you have two blocks of code, and you want to make sure that none of the threads enters the second block until all of them have finished the first block.
You use a CyclicBarrier for that. http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html
You should be able to use a Lock which you take before calling block1 and release after calling block2.
static Lock lock = new ReentrantLock();
Random random = new Random();
public void block1() throws InterruptedException {
System.out.println("Enter block 1");
Thread.sleep(random.nextInt(500));
System.out.println("Leave block 1");
}
public void block2() throws InterruptedException {
System.out.println("Enter block 2");
Thread.sleep(random.nextInt(500));
System.out.println("Leave block 2");
}
private class BlockTester implements Runnable {
long start = System.currentTimeMillis();
#Override
public void run() {
while (System.currentTimeMillis() < start + 10000) {
lock.lock();
try {
System.out.println("Thread: " + Thread.currentThread().getName());
block1();
block2();
} catch (InterruptedException ex) {
System.out.println("Interrupted");
} finally {
lock.unlock();
}
}
}
}
public void test() throws InterruptedException {
Thread[] blockTesters = {
new Thread(new BlockTester()),
new Thread(new BlockTester()),
new Thread(new BlockTester()),
new Thread(new BlockTester()),
new Thread(new BlockTester())
};
for (Thread t : blockTesters) {
t.start();
}
for (Thread t : blockTesters) {
t.join();
}
}
I tried some code to justify the reliability of synchronized block locking mechanism. Consider my sample code
My clocking object.
public class MyLock {
final static Object lock=new Object();
}
Class with synchronized blocks
public class Sample {
public void a(String input) {
System.out.println(input+" method a");
synchronized (lock) {
System.out.println("inside synchronized block in a");
try {
System.out.println("waiting in a");
Thread.sleep(5000);
System.out.println("calling b() from a");
new Sample().b("call from a");
System.out.println("waiting again in a");
Thread.sleep(5000);
System.out.println("Running again a");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void b(String input) {
System.out.println(input+" method b");
synchronized (lock) {
System.out.println("bbb " + input);
}
}
}
Test1 class
public class Test1 implements Runnable{
public static void main(String[] args) {
new Thread(new Test1()).start();
new Thread(new Test2()).start();
}
#Override
public void run() {
new Sample().a("call from main");
}
}
Test2 class
public class Test2 implements Runnable {
#Override
public void run() {
new Sample().b("call from main");
}
}
I just did this because I thought there will be a dead lock scenario if same thread witch holding the lock is going to access another method witch locked using same lock. Now consider the out put
call from main method a
call from main method b
inside synchronized block in a
waiting in a
calling b() from a // i thought this will cause a dead lock
call from a method b
bbb call from a
waiting again in a
Running again a
bbb call from main
Now you can see there is no such issue. My question is how Java manage this situation?
synchronized block is Reentrant
By default the lock (mutex to be precise) used in synchronized block is Reentrant, which means if the same thread tries to acquire the same lock again it will not have to wait and will immediately enter the critical block as it already owns that lock.
Where is Reentrancy useful?
Simple answer is Recursion.
Consider the scenario of recursion on a synchronized method,
int synchronized method(int param){
//... some logic
method(param - 1);
}
In this example you would not want the same thread to be blocked for the same lock, as it will never be able to proceed.
Deadlock occurs in this scenario:
Thread A acquires lock A
Thread B acquires lock B
Thread A tries to acquire lock B
Thread B tries to acquire lock A
Now in this situation no one will be able to proceed and hence deadlock. But in your scenario there is only one lock, so the other thread will just wait for the first thread to leave the lock and then continue.
Since your lock object is static it is shared among threads. Once thread A has acquired the lock, and when thread B enters method B of sample class it tries to acquire the same lock Which is owned by thread A. So there is no chance of deadlock.
Problem could have been where thread A tries to acuire the lock it already holds in method B, but this hasnt happened in your case as synchnorized block itself is reenterant but if you would have implemented your own lock class and if you wouldnt have cjecked for renterency, there would have been a dead lock.
Iam new to syncronization and multithreading please answer why this code is not getting a lock on object b.
public class Tetsclass {
public static void main(String[] args) {
B b = new B();
A a = new A(b);
A2 a2 = new A2(b);
Thread t1= new Thread(a);
Thread t2= new Thread(a2);
t1.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.start();
}
}
class B {
public synchronized void waitfor() {
synchronized (B.class) {
System.out.println("Lock aquired on "+System.currentTimeMillis());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Lock released");
}
}
public void readObject() {
System.out.println("readobject by thread==="+Thread.currentThread().getName()+" on "+System.currentTimeMillis());
}
}
class A2 implements Runnable {
B b=null;
public A2(B b) {
this.b = b;
}
#Override
public void run() {
b.readObject();
}
}
class A implements Runnable {
B b=null;
public A(B b) {
this.b = b;
}
#Override
public void run() {
b.waitfor();
}
}
I expected the output :
Lock aquired on 1380016080337
Lock released
readobject by thread===Thread-1 on 1380016082337
but the output is :
Lock aquired on 1380016080337
readobject by thread===Thread-1 on 1380016082337
Lock released
The readObject method, including its invocation from A2#run, involves no lock acquisition. Therefore the lock your other thread is holding is inconsequential to the progress of the execution of readObject.
Apparently you have a misunderstanding of the semantics of locks. You believe that when you lock B.class, you have locked "the whole class". The state of matters is quite different: B.class is just another object, and all objects have their associated monitor, which can be acquired by a thread. Mutual exclusion happens only between threads which contend to acquire one and the same lock. There is no semantic relationship between an object as a lock and any of its methods, and the same stands for class objects vz. instances of that class.
One way your misunderstanding may have arisen is via the objects used implicitly on synchronized methods: a synchronized instance method acquires its this as a lock, while a synchronized static method acquires a lock on its associated class object.
Its behaving as expected.
Here is what happens on the time line
a - calls wait (which sleeps 5 secs before releasing lock)
a2 - calls read which prints read message.
t t+dt t+dt+5
---------|-----------|--------------------------------|--------------------------|----------
[a starts] [print(lock acquired)] [sleeps(5)] [print(lock released)]
t+2
----------------------------|--------------|--------------------------|--------------
[a2 starts] [print(read message)]
There is no locking of any kind in your readObject()
Since the readObject() doesn't require to acquire a lock, it won't wait for the other thread to release the lock. This confusion might have come because of the Thread.sleep(2000) you've in your test class.
Try to change that to Thread.sleep(10000) and see the output. You'll get your desired result.
In the first case, the A2 thread will wait for 2 secs after A starts, and will execute without any further delay whereas your A is held up for 5 secs when it acquired the lock.
In the second case, the A2 thread will wait for 10 secs after A starts, and within those 10 secs, your A will start, sleep for 5 secs and release the lock, after which your A2 will be executed without any delays.
Class B object can be synchronized to get the output as expected. There is no synchronization is involve in current code execution. To synchronized this code and get the expected output, we can modify Class B as
class B {
public synchronized void waitfor() {
synchronized (B.class) {
System.out.println("Lock aquired on "+System.currentTimeMillis());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Lock released");
}
}
public void readObject() {
synchronized(B.class)
{
System.out.println("readobject by thread==="+Thread.currentThread().getName()+" on "+System.currentTimeMillis());
}
}
}
Here is a code i am having problem with --
public class WaitTest {
public static void main(String[] args) {
Runner rr = new Runner();
Thread t1 = new Thread(rr,"T1");
Thread t2 = new Thread(rr,"T2");
t1.start();
t2.start();
}
}
class Runner implements Runnable{
int i=0;
public void run(){
try{
if(Thread.currentThread().getName().equals("T1")){
bMethod();
aMethod();
}
else{
aMethod();
bMethod();
}
}catch(Exception e){}
}
public synchronized void aMethod() throws Exception{
System.out.println("i="+i+",Now going to Wait in aMethod "+Thread.currentThread().getName());
Thread.currentThread().wait();
System.out.println("Exiting aMethod "+Thread.currentThread().getName());
}
public synchronized void bMethod() throws Exception{
System.out.println("i="+i+",Now going to Wait bMethod "+Thread.currentThread().getName());
i=5;
notifyAll();
System.out.println("Exiting bMethod "+Thread.currentThread().getName());
}
}
The output is :
i=0,Now going to Wait bMethod T1
Exiting bMethod T1
i=5,Now going to Wait in aMethod T1
i=5,Now going to Wait in aMethod T2
My question is :
Why T2 enters in aMethod while T1 is waiting inside? and Why T2 prints
i=5 in aMethod.
When you execute wait, your thread releases the lock and enters the wait state. At this time the other thread is allowed to enter the method. You are using a single instance of Runnable so when one thread sets it to 5, that's what the other thread reads.
1. wait will immediately release the lock, and handover the lock to the other thread.
2. notify will release the lock only when the closing parenthesis of the synchronized block
is reached.
3. As there is only one instance of Runnable here, its after the i = 5, and when the synchronized block ends..then the lock is released.
This code is not doing the wait-notify pattern. The Thread.currentThread().wait() call throws an IllegalMonitorStateException, which is caught and ignored by the run method. Both T1 and T2 throws this exception, and hence you do not see the line Exiting aMethod printed.
The notify call in bMethod is wasted, because no thread ever waits on the intrinsic lock of the rr Runnable.