import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
Lock lck=new ReentrantLock();
public void lockIt(){
lck.lock();
for(int i=0;i<10;i++) {
System.out.println("i : "+ i);
try{Thread.sleep(200);} catch (Exception e){}
}
lck.unlock();
}
public void test()
{
synchronized(this) **// mark 1**
{
for(int j=0;j<10;j++)
{
System.out.println("val is"+j);
try{Thread.sleep(200);}catch (Exception e){}
}
}
}
public static void main(String[] args) {
LockTest obj=new LockTest();
new Thread(new Runnable() {
#Override
public void run() {
obj.lockIt();
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
obj.test();
}
}).start();
}
}
}
// In above case when we say lck.lock(); then lock is acquired on
which object actually ? is it "this" or the "lck" itself ?
even if the lock gets acquired on either of "this" or "lck" object
then how diff. threads are able to enter into the critical sections
locked by the same "this" or "lck" object.
case 1: when we use synchronized(this) at mark1..
case 2: when we use synchronized(lck ) at mark 1..
in both the cases both the loops runs in parallel.
The lock obtained by lck.lock() (which is on the lck object) is completely unrelated to the lock obtained by synchronized(this) or synchronized(lck).
If you want to protect critical sections, then all threads have to use the same locking mechanism (and the same lock).
java.util.concurrent.locks.Lock is a different mechanism introduced for cases where the synchronized keyword is not flexible enough. In particular, the synchronized keyword automatically obtains and releases locks as execution enters and leaves a block. It is not possible there to obtain a lock in one method, store it somewhere, leave the method and release the lock sometime later. With the Lock object you can do these things (and it also offers lock wait timeouts, whereas synchronized will potentially block forever).
#Thilo has answered most of it, just to add one point from your code, ensure that you are unlocking in the finally block as shown below, otherwise, there is a possibility that you will be ending up with a dead lock.
public void lockIt(){
lck.lock();
try {
for(int i=0;i<10;i++) {
System.out.println("i : "+ i);
try{Thread.sleep(200);}catch (Exception e){}
}
} finally { //important
if(lck != null) {
lck.unlock();
}
}
}
Related
Can this code deadlock with thread 1 calling one and thread 2 calling two. That is, can the acquisition of the inner lock be reordered to before the acquisition of the outer one (from the POV of the other thread)?
private final Object foo = new Object();
synchronized void one() {
// ...
synchronized(this.foo) {
// ...
}
// ...
}
synchronized void two() {
// ...
synchronized(this.foo) {
// ...
}
// ...
}
No, this will not deadlock.
When synchronized methods are called the intrinsic lock of this is locked before the method’s body is executed. Here either thread 1 or thread 2 will get to run its method, and the other one will not be able to lock on the intrinsic lock of this.foo so the owner of the lock of this will be able to lock this.foo.
So for with a Simple Test :
class LockTest implements Runnable {
public final Object foo = new Object();
boolean runOne;
public LockTest(boolean runOne) {
this.runOne = runOne;
}
synchronized void one() {
System.out.println("runnin one function");
synchronized(this.foo) {
try {
System.out.println("Enter Sleep function one");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized void two() {
System.out.println("running two function");
synchronized(this.foo) {
try {
System.out.println("enter sleep function two");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void run() {
if(runOne)
one();
else
two();
}
}
With this in a Main class :
while (true)
{
LockTest document2 = new LockTest(true);
LockTest document3 = new LockTest(false);
Thread tread1 = new Thread(document2);
Thread tread2 = new Thread(document3);
tread1.start();
tread2.start();
a++;
if(a==10)
break;
}
We are not locking and even watching with a Thread Dump everything is working Fine. Why? Because every time we are initializating a new Thread with a new object foo. But if that object is declared as static it will be a lock and the others threads need to wait. So from my test and POV. No, it can't be deadlocked.
On my computer, using java 8, the following program won't stop even if map access is synchronized. Aren't those synchronized blocks enougth?
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
// Broken! - How long would you expect this program to run?
public class StopThread {
private static HashMap<String, String> stopRequested = new HashMap<String, String>();
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
synchronized (stopRequested) {
while (stopRequested.get("stop") == null)
i++;
}
System.out.println(i);
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
synchronized (stopRequested) {
stopRequested.put("stop", "true");
}
}
}
This will run forever. The while loop in the synchronized block is effectively infinite since it is entered first - thus prohibiting the second synchronized block from ever being entered.
Yes that is expected, your backgroundThread is holding the lock before your main thread and it wont release it until the main thread writes "stop" to the map, the main thread needs the lock to write it the "stop" so basically this is a dead lock.
There are several ways to solve this deadlock, my guess is what you are trying to do is to see how many times you count before the main thread writes "stop" entry in your map.
You can simply acquire and release your lock on each iteration of the loop which makes sense for your scenario.
while (stopRequested.get("stop") == null)
synchronized (stopRequested) {
i++;
}
Another solution could be using concurrentHashMap, check this link for more details
You have two threads synchronizing on stopRequested. Only one synchronized block is permitted to run at any given time. Since it will almost always be the case that backgroundThread’s synchronized block runs first, it will never exit and thus will never allow any other thread to synchronize on stopRequested.
The wait and notify methods exist precisely to solve this problem:
try {
int i = 0;
synchronized (stopRequested) {
while (stopRequested.get("stop") == null) {
stopRequested.wait();
i++;
}
}
System.out.println(i);
} catch (InterruptedException e) {
throw new RuntimeException(i);
}
// ...
synchronized (stopRequested) {
stopRequested.put("stop", "true");
stopRequested.notify();
}
The reason this works is that wait() will temporarily, and atomically, release the synchronized lock, allowing another thread to synchronize on that object.
Note that wait() must be called in a loop which checks the condition being waited for, since wait() can occasionally return even if no other thread called notify(). This “spurious wakeup” is due to the nature of threads on some systems.
A well-behaved thread will place the entire wait-loop in a try/catch block, so the thread will exit when interrupted. An interrupt is a request from some other thread asking your thread to stop what it’s doing and exit cleanly.
Thanks for all the answers. Indeed, this is a deadlock. A working synchronization is
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
// Broken! - How long would you expect this program to run?
public class StopThread {
private static HashMap<String, String> stopRequested = new HashMap<String, String>();
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (stopRequested())
i++;
System.out.println(i);
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
synchronized (stopRequested) {
stopRequested.put("stop", "true");
}
}
static boolean stopRequested()
{
synchronized (stopRequested) {
return stopRequested.get("stop") == null;
}
}
}
Here is my code
class Thread1 extends Thread
{
public synchronized void show()
{
System.out.println("show");
System.out.println(Thread.currentThread().getName());
try
{
Thread.sleep(5000);
}
catch(Exception e)
{
System.out.println(e);
}
}
public synchronized void display()
{
System.out.println("Display");
System.out.println(Thread.currentThread().getName());
}
public static void main(String args[])
{
Thread1 z=new Thread1();
z.set();
}
public void set()
{
Thread1 tr=new Thread1();
Thread1 tr1=new Thread1();
tr.start();
tr1.start();
}
public void run()
{
try
{
show();
display();
}
catch(Exception e)
{
System.out.println(e);
}
}
}
I assume you meant to ask about why show is printed by both threads before either of the thread names are printed.
You are synchronizing your instance methods, so they are implicitly locking on the object on which the method is called. However, you have 2 different Thread1 objects locking on themselves, so neither thread is stopping the other from entering the synchronized methods.
If you intend to have only one Thread execute each of the synchronized methods at a time, then you need to lock on a common object. Use a synchronized block that locks on Thread1.class.
Here is what that looks like for the show method.
public void show()
{
synchronized (Thread1.class)
{
System.out.println("show");
System.out.println(Thread.currentThread().getName());
try
{
Thread.sleep(5000);
}
catch (Exception e)
{
System.out.println(e);
}
}
}
The display method can be modified similarly.
You are instantiating two different objects that have their own state (tr and tr1). They never access the same synchronised block, and thus never block waiting for the other one to finish.
Try moving the show method to another class, instantiate that class and then pass it to tr and tr1 as a constructor parameter, for example.
Am I not using synchronization properly:
In following code i am having 2 problems :
1. while makingmethods (designBusiness,createBusiness,sellBusiness) as synchronized like in this case, a call to wait() says IllegalMonitorStateException but i can not understand why? because in designBusiness method Designer Thread do get a lock so it is supposed to wait on wait call. I am getting IllegalMonitorStateException on wait() and notify() both.
2.Even though when i remove synchronized keyword and use synchronized(this) block for particularly wait() and notify() still i got DEADLOCK! WHY?
public class Main {
HashMap<String, Integer> map = new shop().orderBook();
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
main.sellBusiness();
Thread.sleep(3000);
main.designBusiness();
Thread.sleep(3000);
main.createBusiness();
}
private synchronized void designBusiness() throws InterruptedException {
Thread designThread = new Thread(new Runnable() {
public void run() {
Set set = map.keySet();
System.out.println("Tracking OrderList");
System.out.println(set.size());
try {
System.out.println("waiting.........");
wait();
System.out.println("wait completed");
System.out.println("after design process items in orderList are "
+ map.keySet().size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "Designer Thread");
designThread.start();
System.out
.println("status of Designer Thread" + designThread.isAlive());
}
private synchronized void createBusiness() throws InterruptedException {
Thread createThread = new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()
+ " started");
Creator creator = new Creator();
creator.create(map);
notifyAll();
System.out.println("notified");
}
}, "Creator Thread");
createThread.start();
createThread.join();
System.out.println("status of Creator Thread" + createThread.isAlive());
}
private void sellBusiness() throws InterruptedException {
Thread sellThread = new Thread(new Runnable() {
public void run() {
Seller seller = new Seller();
seller.sellGold(45000, 15);
seller.sellSilver(14000, 60);
seller.noteOrder("Mrs Johnson", 15000, map);
seller.noteOrder("Mr. Sharma", 10000, map);
seller.sellGold(60000, 20);
seller.noteOrder("Mr. Hooda", 17500, map);
System.out.println(Thread.currentThread().getName()
+ " done selling");
}
}, "Seller Thread");
sellThread.start();
sellThread.join();
System.out.println("status of seller Thread" + sellThread.isAlive());
}
}
please help i could not find any solution for this problem and i am searching from last night.
If you got this exception you are not in a block or method that is synchronised on the object you are waiting on. That is the meaning of the exception. The only meaning.
The wait() method you are calling is executed on the instance of the anonymous inner class you are creating. The synchronised method you are creating it from is synchronised on a different object, and it has probably also already executed by the time the inner object gets to the wait() call.
You need to sort out which object is which here. Probably you need to call Main.this.wait(), but it depends on what you think you're trying to do, which isn't clear from your question.
NB you aren't getting a deadlock, you are getting an infinite block. It isn't the same thing.
wait(), notify() and notifyAll() must be used with synchronized. What I would do is trying to solve the deadlock.
To illustrate why you got deadlock (unrelated code removed) (if I guessed right):
public class Main {
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
main.createBusiness();
}
private synchronized void createBusiness() throws InterruptedException {
// ^^^^^^^^^^^^ got lock
Thread createThread = new Thread(new Runnable() {
public void run() {
synchronized (Main.this) {
// ^^^^^^^^^^^^^^^^^^^^^^^^ try to get lock --> DEADLOCK
Main.this.notifyAll();
}
}
});
createThread.start();
createThread.join();
// ^^^^^^^^^^^^^^^^^^^ wait for createThread to die --> DEADLOCK
}
}
Main thread got the lock of Main.this.
createThread tried to get lock of Main.this, but it's locked by Main.this, hence waiting.
Main thread waited for createThread to die, hence waiting. (2 and 3 can be swapped)
Since I'm not sure what you tried to achieve, I'm not sure if the following is the right solution, but you can try (even if the above guessed wrong):
First, create a lock object.
public class Test {
private Object lock = new Object();
Second, in designer thread
synchronized (lock) {
lock.wait();
}
Third, in creator thread
synchronized (lock) {
lock.notifyAll();
}
wait() must be executed from synchronized block on the same monitor. Since wait() is the same as this.wait() you have to wrap it with synchronized(this):
synchronized(this) {
wait();
}
If you try to unlock an onject by a threas which is not locked by that thread then you may end up with the same error.
How can two threads access a synchronized block simultaneously? That is, how can I make one thread give the chance for the other thread to execute a synchronized block, even before this thread finishes the execution of the same synchronized block?
See wait(), notify(), and notifyAll().
Edit: The edit to your question is incorrect. The sleep() method does not release the monitor.
For example:
private static final Object lock = new Object();
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(new One());
executorService.execute(new Two());
}
static class One implements Runnable {
#Override
public void run() {
synchronized (lock) {
System.out.println("(One) I own the lock");
System.out.println("(One) Giving up the lock and waiting");
try {
lock.wait();
} catch (InterruptedException e) {
System.err.println("(One) I shouldn't have been interrupted");
}
System.out.println("(One) I have the lock back now");
}
}
}
static class Two implements Runnable {
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.err.println("(Two) I shouldn't have been interrupted");
}
synchronized (lock) {
System.out.println("(Two) Now I own the lock (Two)");
System.out.println("(Two) Giving up the lock using notify()");
lock.notify();
}
}
}
It sounds like you might want to consider using more than one synchronized block, particularly if there's a blocking operation that one thread is getting caught on and thus blocking another thread that wants to execute something else in the block.
A synchronized block is a block of code which can (by definition) only be accessed by one thread at a time.
Saying that you want another thread to enter this block while another thread also currently processes it, does make the synchronized block scheme useless.
You probably want to split the synchronized block into many other ones.
The only way I can see if one thread calls wait() on monitor object. Then it will release monitor and wait for notification while other thread can execute synchronized block. Then other thread will have to call notify()/notifyAll() so first thread gets monitor back and continue.
A thread can release its monitor using lock.wait(). Another thread can then pick up the monitor and enter the synchronized block.
Example:
public class MultipleThreadsInSynchronizedBlock {
public static void main(String... args) {
final Object lock = new Object();
Runnable runnable = new Runnable() {
public void run() {
synchronized (lock) {
System.out.println("Before wait");
try {
lock.wait();
} catch (InterruptedException e) {
}
System.out.println("After wait");
}
}
};
new Thread(runnable).start();
new Thread(runnable).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
synchronized (lock) {
lock.notifyAll();
}
}
}
This prints:
Before wait
Before wait
After wait
After wait
However it's not a "hack" to allow a mutually exclusive block to be run non-atomically. If you're going to use very low-level synchronization primitives like this you need to know what you're doing.