Why is it that two synchronized blocks can't be executed simultaneously by two different threads in Java.
EDIT
public class JavaApplication4 {
public static void main(String[] args) {
new JavaApplication4();
}
public JavaApplication4() {
Thread t1 = new Thread() {
#Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-1")) {
test(Thread.currentThread().getName());
} else {
test1(Thread.currentThread().getName());
}
}
};
Thread t2 = new Thread(t1);
t2.start();
t1.start();
}
public synchronized void test(String msg) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
System.out.println(msg);
}
}
public synchronized void test1(String msg) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
System.out.println(msg + " from test1");
}
}
}
Your statement is false. Any number of synchronized blocks can execute in parallel as long as they don't contend for the same lock.
But if your question is about blocks contending for the same lock, then it is wrong to ask "why is it so" because that is the purpose of the whole concept. Programmers need a mutual exclusion mechanism and they get it from Java through synchronized.
Finally, you may be asking "Why would we ever need to mutually exclude code segments from executing in parallel". The answer to that would be that there are many data structures that only make sense when they are organized in a certain way and when a thread updates the structure, it necessarily does it part by part, so the structure is in a "broken" state while it's doing the update. If another thread were to come along at that point and try to read the structure, or even worse, update it on its own, the whole thing would fall apart.
EDIT
I saw your example and your comments and now it's obvious what is troubling you: the semantics of the synchronized modifier of a method. That means that the method will contend for a lock on this's monitor. All synchronized methods of the same object will contend for the same lock.
That is the whole concept of synchronization, if you are taking a lock on an object (or a class), none of the other threads can access any synchronized blocks.
Example
Class A{
public void method1()
{
synchronized(this)//Block 1 taking lock on Object
{
//do something
}
}
public void method2()
{
synchronized(this)//Block 2 taking lock on Object
{
//do something
}
}
}
If one thread of an Object enters any of the synchronized blocks, all others threads of the same object will have to wait for that thread to come out of the synchronized block to enter any of the synchronized blocks. If there are N number of such blocks, only one thread of the Object can access only one block at a time. Please note my emphasis on Threads of same Object. The concept will not apply if we are dealing with threads from different objects.
Let me also add that if you are taking a lock on class, the above concept will get expanded to any object of the class. So if instead of saying synchronized(this), I would have used synchronized(A.class), code will instruct JVM, that irrespective of the Object that thread belongs to, make it wait for other thread to finish the synchronized block execution.
Edit: Please understand that when you are taking a lock (by using synchronized keyword), you are not just taking lock on one block. You are taking lock on the object. That means you are telling JVM "hey, this thread is doing some critical work which might change the state of the object (or class), so don't let any other thread do any other critical work" . Critical work, here refers to all the code in synchronized blocks which take lock on that particular Object (or class), and not only in one synchronized block.
This is not absolutely true. If you are dealing with locks on different objects then multiple threads can execute those blocks.
synchronized(obj1){
//your code here
}
synchronized(obj2){
//your code here
}
In above case one thread can execute first and second can execute second block , the point is here threads are working with different locks.
Your statement is correct if threads are dealing with same lock.Every object is associated with only one lock in java if one thread has acquired the lock and executing then other thread has to wait until first thread release that lock.Lock can be acquired by synchronized block or method.
Two Threads can execute synchronized blocks simultaneously till the point they are not locking the same object.
In case the blocks are synchronized on different object... they can execute simultaneously.
synchronized(object1){
...
}
synchronized(object2){
...
}
EDIT:
Please reason the output for http://pastebin.com/tcJT009i
In your example when you are invoking synchronized methods the lock is acquired over the same object. Try creating two objects and see.
Related
I have the following piece of code. It has two objects, namely MultiThreadingTest, and the ThreadB object. When we say synchronized(b), what does it mean exactly? Can the 'main' thread get a lock on b before ThreadB finishes it's execution? I can't understand the significance of monitor object in the synchronized block.
package threads;
class MultiThreadingTest
{
public static void main(String[] args)
{
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b)
{
System.out.println("Current thread : "+ Thread.currentThread().getName());
try
{
System.out.println("Waiting for b to complete...");
b.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Total = "+b.total );
}
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this)
{
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i=0;i<100;i++)
{
total = total + i;
}
notify();
}
}
}
Think of it like the child's game, whoever holds the [whatever object] gets to speak. Whoever holds the monitor object gets to execute in computing terms.
The monitor is the object you are locking upon, at any given time, only one thread accesses code protected by a synchronization block per monitor object. The object itself is arbitrary and doesn't hold much weight onto synchronization (though you have to watch out for reassigning variables as well as null references). Also, JB Nizet raises a good point here on synchronizing on a Thread object since many internal VM methods do that, you can cause bazaar, hard to detect bugs and deadlocks.
Two threads entering different synchronization blocks locking on different monitors will execute concurrently, analogous to two separate groups of people playing/enacting the "who ever holds to xxx gets to speak" game. Locking on this is just a convenient way to manifest a single lock synchronization without creating additional lock objects.
In your case, ThreadB b is the same object pointed to as this from within the ThreadB class meaning that only one thread can enter any of your defined synchronization blocks at once. The order is highly dependent on which thread ran first, the thread scheduler and even the underlying system.
The main reason for monitor objects is so that complex thread-safety mechanisms can be realized. Imagine a system where every synchronization block is single thread access (i.e. at any time, any thread enters a synchronization block will hold every other thread in the whole VM trying to enter a sync block) not only will this cause a massive performance slowdown, it just doesn't make sense. Why should two unrelated application modules lock on each other if they share no data and never interact?
The solution of course is to have one module use one (or several) monitor objects that are unrelated/unassociated with the other module, so both can execute concurrently independent of each other (assuming this is the desired behavior).
To further clarify, you could write:
class MultiThreadingTest{
public static void main(String[] args){
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b.lock){
System.out.println("Current thread : "+ Thread.currentThread().getName());
try{
System.out.println("Waiting for b to complete...");
b.lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total = " + b.total );
}
}
}
class ThreadB extends Thread{
public final Object lock = new Object();
int total;
public void run(){
synchronized(lock){
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i = 0; i < 100; i++){
total = total + i;
}
lock.notify();
}
}
}
to exactly the same effect as the code you've used (even better, since it resolves the conflict with Thread.join() and other methods).
synchronized(this) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by this.
synchronized(b) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by b.
They thus do the exact same thing. The only difference is the object that is used to lock.
Note that waiting, synchronizing and notifying on an object of type Thread is a really really bad idea. It confuses things, and will lead to unwanted behavior because other methods (join() for example) also use the Thread as a monitor.
As per my understanding, no. The 'this' object within the run() method and the 'b' object in the main() method are the same.
Hence it would not be possible for the 'main' thread to acquire the lock until the thread completes execution.
Also the notify() within the run() method seems to be redundant in this case since its at the end of the method and the lock on the monitor would be relinquished any how.
PS: Do look around for similar questions that may already have been asked in the forum. They may help in providing additional understanding.
If there is a synchronized block which is taking lock on an object, say StringBuilder sb, which one thread is executing this synchronized block in which sb is locked, suppose there is another thread which is calling another method which will try to change the value of sb(not in synchronized block), then, will it be allowed to do that?
public static void main(String[] args) {
A a = new A();
new Thread(new MyRunnable(a), "T1").start();
new Thread(new MyRunnable(a), "T2").start();
}
static class MyRunnable implements Runnable {
A a;
public MyRunnable(A a) {
super();
this.a = a;
}
#Override
public void run() {
while (true) {
if ("T1".equals(Thread.currentThread().getName())) {
a.m1();
} else {
a.m2();
}
}
}
}
static class A {
StringBuilder abc = new StringBuilder("fdfd");
public void m1() {
synchronized (abc)
{
System.out.println("abc locked : " + abc);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();}
System.out.println("abc released: " + abc);
}
}
public void m2() {
System.out
.println(Thread.currentThread().getName() + " running");
System.out.println("trying to access abc");
abc.append("A");
System.out.println("abc accessed");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();}
}
}
}
I thought locking an object would not allow to change that object as well from being modified or accessed. But, from output I am seeing the locked object can be modified:
OUTPUT:
abc locked : fdfd
T2 running
trying to access abc
abc accessed
T2 running
trying to access abc
abc accessed
T2 running
trying to access abc
abc released: fdfdAA
abc accessed
abc locked : fdfdAAA
T2 running
I am not getting this, can anybody please explain this. What is the use of taking a lock on an object? Is it just because wait/notify/notifyAll methods?
If there is a synchronized block which is taking lock on an object, say StringBuilder sb, which one thread is executing this synchronized block in which sb is locked, suppose there is another thread which is calling another method which will try to change the value of sb(not in synchronized block), then, will it be allowed to do that?
Uh yes. I think you need to do some reading about what synchronized does. See the Java tutorial. It does not "lock" an object as in restrict other threads from operating on it. What it does is provide mutex for the surrounded block of code for threads that lock on the same object instance. The fields in an object are perfectly able to be mutated both inside or outside the synchronized block.
It is always a good idea to synchronize on a constant object so I tend to do something like:
private final Object lock = new Object();
...
synchronized (lock) {
// only one thread allowed inside this block at a time
}
If multiple threads are accessing some sort of thread-unsafe object, I will synchronize on that object and do the operations on the object inside the synchronized block:
private final SomeUnsafeObject someObject = ...;
...
synchronized (someObject) {
// only one thread allowed inside this block at a time
someObject.someUnsafeMethodCall(...);
}
// no accesses (read or write) outside of the synchronized block
I thought locking an object would not allow to change that object as well from being modified or accessed. But, from output I am seeing the locked object can be modified:
No, there is no implicit blocking of the object being changed. If you only access the object's fields inside of the synchronized block then you would have accomplished what you want.
public void m2() {
...
abc.append("A");
Right, since you are not inside of a synchronized (abc) block here, there is nothing that stops the thread from calling abc.append(...).
I am not getting this, can anybody please explain this. What is the use of taking a lock on an object? Is it just because wait/notify/notifyAll methods?
Synchronization allows you to control access to a block of code to one thread at a time based on the lock object (or the monitor on that object to be precise). It also allows you to do lock.wait(...) and lock.notify(...) to control the threads operation and block/release them as well.
Synchronization also puts up memory barriers so that a thread will see changes stored to central memory when it enters a synchronized block and will see it's changes written to central memory when it leaves. Without these memory barriers, if other threads access the StringBuilder without synchronization then they may seem some partially updated portion of that class which can cause NPEs or other failures.
A thread will only have to wait to access a locked code region, if that lock is held by another thread. However, it doesn't have to wait if it doesn't need a lock, i.e., your StringBuilder instance is only safe if every access is surrounded by a synchronized block locking on the same lock.
In your case, since access to abc in method m2() is not in synchronized block, a thread doesn't need a lock, and hence can access it.
When you are synchronizing on a Lock object the lock object has to be accessible by all threads, so either use a static object or a field belonging to the calling code.
Then you code will work to have only only one thread at a time accessing a certain block(s) of code. It will not prevent you acting in that code in anyway that you wish, but only one Thread can do it at one time.
I want to clear my understanding that if I surround a block of code with synchronized(this){} statement, does this mean that I am making those statements atomic?
No, it does not ensure your statements are atomic. For example, if you have two statements inside one synchronized block, the first may succeed, but the second may fail. Hence, the result is not "all or nothing". But regarding multiple threads, you ensure that no statement of two threads are interleaved. In other words: all statements of all threads are strictly serialized, even so, there is no guarantee, that all or none statements of a thread gets executed.
Have a look at how Atomicity is defined.
Here is an example showing that the reader is able to ready a corrupted state. Hence the synchronized block was not executed atomically (forgive me the nasty formatting):
public class Example {
public static void sleep() {
try { Thread.sleep(400); } catch (InterruptedException e) {};
}
public static void main(String[] args) {
final Example example = new Example(1);
ExecutorService executor = newFixedThreadPool(2);
try {
Future<?> reader = executor.submit(new Runnable() { #Override public void run() {
int value; do {
value = example.getSingleElement();
System.out.println("single value is: " + value);
} while (value != 10);
}});
Future<?> writer = executor.submit(new Runnable() { #Override public void run() {
for (int value = 2; value < 10; value++) example.failDoingAtomic(value);
}});
reader.get(); writer.get();
} catch (Exception e) { e.getCause().printStackTrace();
} finally { executor.shutdown(); }
}
private final Set<Integer> singleElementSet;
public Example(int singleIntValue) {
singleElementSet = new HashSet<>(Arrays.asList(singleIntValue));
}
public synchronized void failDoingAtomic(int replacement) {
singleElementSet.clear();
if (new Random().nextBoolean()) sleep();
else throw new RuntimeException("I failed badly before adding the new value :-(");
singleElementSet.add(replacement);
}
public int getSingleElement() {
return singleElementSet.iterator().next();
}
}
No, synchronization and atomicity are two different concepts.
Synchronization means that a code block can be executed by at most one thread at a time, but other threads (that execute some other code that uses the same data) can see intermediate results produced inside the "synchronized" block.
Atomicity means that other threads do not see intermediate results - they see either the initial or the final state of the data affected by the atomic operation.
It's unfortunate that java uses synchronized as a keyword. A synchronized block in Java is a "mutex" (short for "mutual exclusion"). It's a mechanism that insures only one thread at a time can enter the block.
Mutexes are just one of many tools that are used to achieve "synchronization" in a multi-threaded program: Broadly speaking, synchronization refers to all of the techniques that are used to insure that the threads will work in a coordinated fashion to achieve a desired outcome.
Atomicity is what Oleg Estekhin said, above. We usually hear about it in the context of "transactions." Mutual exclusion (i.e., Java's synchronized) guarantees something less than atomicity: Namely, it protects invariants.
An invariant is any assertion about the program's state that is supposed to be "always" true. E.g., in a game where players exchange virtual coins, the total number of coins in the game might be an invariant. But it's often impossible to advance the state of the program without temporarily breaking the invariant. The purpose of mutexes is to insure that only one thread---the one that is doing the work---can see the temporary "broken" state.
For code that use syncronized on that object - yes.
For code, that don't use syncronized keyword for that object - no.
Can we say that by synchronizing a block of code we are making the contained statements atomic?
You are taking a very big leap there. Atomicity means that the operation if atomic will complete in one CPU cycle or equivalent to one CPU cycle whereas Synchronizing a block means only one thread can access the critical region. It may take multiple CPU cycles for processing code in the critical region(which will make it non atomic).
...
lock.lock()
try{
...
}
finally{
lock.unlock()}
...
I noticed that this doesn't insure absolute mutual exclusion where as synchronized always does, so what are exactly the differences between both?
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Guys extends Thread{
public static void go()throws InterruptedException{
final Lock lock = new ReentrantLock();
lock.lock();
try{
System.out.println("global " + main.global);
main.global = main.global + 100;
}
finally
{
lock.unlock();
}
}
public void run(){
try{
for(int i = 0; i <1; i++)
{
System.out.println(this);
go();
}
} catch(InterruptedException e)
{
System.out.println("Interrupted Exception caught");
}
}
}
My threads are sharing a single resource. Only synchronized works in this case.
You're creating a new Lock object with every invocation of the method so each thread locks on a different object.
Take out this line
final Lock lock = new ReentrantLock();
Outside the method making it a class member and it should work correctly.
#Edit: ok more in-depth explanation:
Making a method synchronized protects it with a lock on an object just like you'd do it with a Lock object yourself. If it's a non static method the lock is done on "this" object. Since you have a static method here the lock will be on the object representing your Guys class. There is one such object so there will be only one lock to be obtained. If one thread holds the lock others have to wait.
What you are doing here is creating a new Lock object on every invocation of go() method therefore each thread calling the go() method acquires a different lock which defends you from nothing because only that thread can call lock.lock() on it (as I said other threads will invoke lock() on their own instances of Lock).
Taking this Lock variable out of the method and making it a class variable will mean that all the threads invoking the go() method will try to acquire the same lock - similar to what synchronized does.
#Edit2: to show it more vividly it is like when there is a group of people and only the person holding a stick can speak. All is ok when there is only 1 stick (which is the case with synchronized method or a shared Lock object). But obviously when it is a group of Polish people (editorial note I am Polish so I can make fun of my own people) everyone will bring their own stick with them (and it is similar with your new ReentrantLock() here). This will result in everyone speaking at the same time. And obviously everyone will be like "omg but I have a stick, I have the full right to speak now!".
synchronnized block are some useful but non customizeable way to grant that only one thread can access critical code block. Let's review some lock objects that give you benefits over synchronized block:
Reenterability - think about synchronous block inside recursion. Are you sure that it is not failed? There ReentrantLock will help you
ReadWrite locks - assume that you have 1000 readers to some Map but only 1 writers. The big optimization can be taken if readers can read simultaneously, but locks are taken only for writer. Then try..finally with ReadWriteLock gives you big benefit
I have a java applet. A class inside that applet is creating a thread to do some work, waiting 30 seconds for that work to complete, if its not completed in 30 secs it sets a Boolean to stop the thread. The wait and Boolean change are in a synchronized block, Is this necessary considering there is no other thread running aside from these 2.
System.out.println("Begin Start Session");
_sessionThread = new SessionThread();
_sessionThread.start();
synchronized (_sessionThread)
{
_sessionThread.wait(30000);
_sessionThread._stopStartSession = true;
}
Why couldn't I just do this instead.
System.out.println("Begin Start Session");
_sessionThread = new SessionThread();
_sessionThread.start();
_sessionThread.wait(30000);
_sessionThread._stopStartSession = true;
SessionThread run method. Invokes a JNI method to call a dll to open a program window.
public void run()
{
try
{
startExtraSession();
}
catch (Throwable t)
{
t.printStackTrace();
}
notify();
}
private native void openSessionWindow(String session_file);
private void startExtraSession()
{
final String method_name = "startExtraSession";
String title = _sessionInfo._title;
long hwnd = 0;
openSessionWindow(_sessionInfo._configFile);
try
{
//Look for a window with the predefined title name...
while ((hwnd = nativeFindWindow(title)) == 0 && !_stopStartSession)
{
Thread.sleep(500);
}
}
catch(Throwable t)
{
t.printStackTrace();
}
}
1. Is the synchronized really needed?
2. Is there a better way to accomplish this aside from using threads?
A given thread is required to own a lock on a object to be able to call wait(long) on it. This is achieved by using a synchronized block on the said object.
See J2SE specification on using wait.
Acquiring a lock/monitor in java can be done in various ways:
In a synchronized (non-static) method, the thread owns a monitor on the object referenced by this.
In a static synchronized method, the thread owns a monitor on the Class<?> descriptor for the class that defines the said method.
In a synchronized(x) block, the thread owns a monitor on x.
That lock will be released if:
You get outside of the synchronized code block (be it a method, static method, or explicit block).
You have called wait() or one of its variations (and you'll re-acquire it just before the method returns).
Both these two lists may omit specific cases but should cover at least a large portion of the typical use cases.
There's a very simple reason that you need synchronized to call wait
The synchronized makes sure that nobody is calling notify or notifyAll at the same time you're calling wait
For example: Thread 1
synchronized( obj )
{
triggerActionOnThread2();
obj.wait();
}
Thread 2 (triggered by triggerActionOnThread2)
...
synchronized( obj )
{
obj.notify();
}
If you don't have the synchronized blocks, then the notify might happen before (or during) the wait, and then the wait misses the notify, and you can hang Thread 1.
Imagine the above blocks of code without the synchronized blocks, and imagine if Thread 2 is executed all the way through the notify before the wait gets called.
BTW, I ask this very question on interviews for Java engineers when the job will involve multithreaded programming.
Can you please post SessionThread code? You cannot wait if you don't own the lock, so you need synchronized (_sessionThread) to do _sessionThread.wait(30000); Not sure what's with _sessionThread._stopStartSession = true;
If the boolean is the only shared state between the threads, declaring the boolean transient will guarantee that changes to it are seen between the threads as would a synchronization block around access to the boolean.