Why does synchronized(this) works? - java

The "this" object is different for the two threads, since they are two different objects. So they are checking two different locks, so nothing should stop them from running in parallel a critical section :
void method() {
synchronized(this) {
//critical section
}
}
What do I miss ?

If you have a critical section, it usually involves a single object. In these cases, if two different instances run in parallel, there are no race conditions, assuming they only work on instance-local resources, such as private fields.
What you might have missed is if objects of the same type work on a shared resource, synchronized(this) will indeed not block them from accessing it in parallel. In this case you can synchronize on the class itself using synchronized(MyFoo.class) { } or a shared variable.

Here is an example where it is the same object for two threads:
class Test {
void method() {
synchronized(this) {
}
}
public static void main(String[] args) throws Exception {
final Test t1 = new Test();
new Thread() {
public void run() {
t1.method();
};
}.start();
new Thread() {
public void run() {
t1.method();
};
}.start();
}
}

You do not miss anything. If both your threads try to apply synchronized and try to lock monitors of two different objects, they won't block each other.

Every object in Java has a lock mechanism, and only one thread at a time can occupy the lock. When you surround a block of code with synchronize(this) or add a synchronize keyword to a method, it restricts only one thread to those synchronized areas for that object. It has nothing to do with thread instances, nor do two instances of the same class share a lock.

If multiple threads of same Object are calling method(); then at a time only one thread will get object's monitor. but if there are different - different object of same type then they can enter parallel way.
the only problem in this code will happen when you are having any class variable, so that will be shared by all that time you have to use class Level lock.

Related

Multithreading: synchronize by locking

Concurrent collection:
ConcurrentMap<LocalDate, A> ex = new ConcurrentHashMap<>();
class A {
AtomicLong C;
AtomicLong D
}
How can I synchronize by locking "C" and "D"? That is, I need to change "C" and "B" at the same time with a guarantee that while I change the other one, the first one does not change from external actions.
Thank you.
What you're solving for
You are describing that you want to:
allow a caller to modify something on an object
prevent any other callers (other threads) from modifying things at the same time
Solution description
This solution uses synchronized, though there are number of other mechanisms available in Java that would support this (several of which are covered in
the Lock Objects section of the Java Tutorials).
The way "synchronized" works is that you designate some code using the "synchronized" keyword, along with an object to synchronize on.
When your code runs, the JVM will guarantee that, for all code which is synchronized – on the same object – only one thread
can proceed at a time.
You can make a synchronized code block, like below. Note: this defines an Object named "lock", but it's just a name chosen for clarity when
reading the code – you could name it anything you like.
Object lock;
synchronized (lock) {
... // all things here run only when "lock" is available
}
You can also designate an entire method as being synchronized, like this:
public void synchronized print() {
System.out.println("hello");
}
This second example behaves like the first - it also locks on an object – but it's not clear at a glance what the object is; that is, how does
the JVM know which object to sychronize on? This approach works if the method itself is called on an object instance, and in that case the lock becomes this. I'll show an example below.
There's good info in the Java Tutorials about synchronized methods.
Solution #1: synchronized block using Object lock
Here are a few notes about a class AllowOneEditAtATime:
it has two private members: one and two
because they're private, they cannot be changed directly – so it would not be allowed to do something like this:
AllowOneEditAtATime a = new AllowOneEditAtATime();
a.one = new AtomicLong(1); // cannot change "one" directly because it is private
defines private Object lock – this is meant to act as the thing that two different synchronized code blocks will lock on. It's totally fine to have different blocks of code each synchronize on the same object. This is the main technique you're after.
uses a synchronized block inside setOne(), synchronizing on "lock"
uses another synchronized block inside the other method – setTwo() – also synchronizing on "lock"
because both setOne() and setTwo() are synchronized on the same object, one of them will be allowed to run at a time
class AllowOneEditAtATime1 {
private Object lock;
private AtomicLong one;
private AtomicLong two;
public void setOne(AtomicLong newOne) {
synchronized (lock) {
one = newOne;
}
}
public void setTwo(AtomicLong newTwo) {
synchronized (lock) {
two = newTwo;
}
}
}
Solution #2: synchronized block, using this
Solution #1 works fine, but it isn't necessary (in this case) to create an entire object just for locking. Instead, you can rely on the fact that
this code runs only after someone called new AllowOneEditAtATime(), which means there's always an object instance, which means inside the code
you can use this. The this keyword refers to the object instance itself, the actual instance of AllowOneEditAtATime.
So here's a variation using this (no more Object lock):
class AllowOneEditAtATime2 {
private AtomicLong one;
private AtomicLong two;
public void setOne(AtomicLong newOne) {
synchronized (this) {
one = newOne;
}
}
public void setTwo(AtomicLong newTwo) {
synchronized (this) {
two = newTwo;
}
}
}
Solution #3: synchronized methods, implicit lock
Solution #2 works fine, but since we're using this as the lock, and since the code paths fit with doing this, we can use
synchronized methods
instead of synchronized code blocks.
That means we can replace this:
public void setTwo(AtomicLong newTwo) {
synchronized (this) {
two = newTwo;
}
}
with this:
public synchronized void setOne(AtomicLong newOne) {
one = newOne;
}
Under the covers, the entire setOne() method is synchronized on this automatically, so it isn't necessary to
include synchronized (this) { .. }
at all. In Solution #2, both methods were doing that, so both can be replaced.
By synchronizing both methods, they will both be synchronized on the object instance (this), which is similar to Solution #2, but with less code.
class AllowOneEditAtATime3 {
private AtomicLong one;
private AtomicLong two;
public synchronized void setOne(AtomicLong newOne) {
one = newOne;
}
public synchronized void setTwo(AtomicLong newTwo) {
two = newTwo;
}
}
Any of the above would work, as would other synchronization mechanisms. As with all things, there are multiple ways you could solve the problem.
For additional reading,
the Concurrency lesson (in Java Tutorials) has good info
and might be worth your time.

Synchronizing static variables

What I understand by synchronizing static object which is a variable, if one thread is accessing it, other thread can't.
class T3
{
static Integer i = 0;
static void callStatic()
{
synchronized(T3.class)
{
System.out.println(i++);
while(true);
}
}
public void notStatic()
{
System.out.println(i++);
while(true);
}
}
class T2 implements Runnable
{
public void run()
{
System.out.println("calling nonstatic");
new T3().notStatic();
}
}
class T implements Runnable
{
public void run()
{
System.out.println("calling static");
T3.callStatic();
}
}
public class Test
{
public static void main(String[] args)
{
new Thread(new T()).start();
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
}
new Thread(new T2()).start();
}
}
But this demo program has output as :
calling static
0
calling nonstatic
1
Is my understanding wrong? Or am I missing something?
I tried, synchronzing callStatic method, and synchronizing T3.class class object too. But none worked as I thought.
Note : I thought, 1 will not be printed as callStatic has lock on variable i and is in infinite loop.
You don't synchronize on variables, you synchronize on objects.
callStatic synchronizes on 1 and then sets i to 2. If notStatic were to enter a synchronized(i) block at this point, it would synchronize on 2. No other thread has locked 2, so it proceeds.
(Actually, 1 and 2 aren't objects, but Integer.valueOf(1) and Integer.valueOf(2) return objects, and the compiler automatically inserts the Integer.valueOf calls to convert ints to Integers)
In your code, notStatic doesn't actually synchronize at all. It's true that only one thread can be in a synchronized block for a particular object at a particular time, but that has no effect on other threads that are not trying to enter a synchronized block.
Note: This answer relates to the original question, which had synchronized(i), not synchronized(T3.class), in callStatic. The edit really changes the question.
synchronize acts on the object, not the variable/member holding it. There are a couple of important things going on in your code.
synchronize(i) does indeed synchronize access to i provided that the other code trying to use it also synchronizes. It has no effect on code that doesn't synchronize. Suppose Thread A does synchronize(i) and holds it (your infinite loop); then Thread B does System.out.println(i); Thread B can happily read i, there's nothing stopping it. Thread B would have to do
synchronize (i) {
System.out.println(i);
}
...in order to be affected by Thread A's synchronize(i). Your code is (attempting to) synchronized mutation, but not access.
i++; with an Integer is effectively equivalent to i = new Integer(i.intValue() + 1), because Integer is immutable. So it creates a different Integer object and stores that in the i member. So anything synchronizing on the old Integer object has no effect on code synchronizing on the new one. So even if your code were synchronizing both access and mutation, it wouldn't matter, because the synch would be on the old object.
This means that the code in your callStatic is synchronizing on an instance of Integer and then repeated creating a bunch of other instances, which it is not synchronizing on.
Synchronized blocks on static and non static don't block each other. You need to understand how synchronized works for this. Synchronized is done always on an object never on a variable. When you synchronize, thread takes a lock on the object's monitor, the object which you put in the synchronized statement braces.
Synchronized blocks on static references (like in your code) lock on the .class object of your class and not on any instance of that class. So static and non-static synchronized blocks don't block each other.
Now in your code the notStatic method doesn't synchronize on anything where as the callStatic synchronizes on the static i Integer object. So they don't block each other.

what does it mean when we say synchronized(instance field)..?

Attached the code..
what does this mean, synchronized(m)..?? why we should use that..??
What's the difference between synchronized(this) & synchronized(m)..??
class Waiter implements Runnable {
Message m;
public Waiter(Message m) {
this.m = m;
}
#Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (m) {
try {
System.out.println("Waiting to get notified at time " +System.currentTimeMillis());
m.wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Waiter thread notified at time "+System.currentTimeMillis());
System.out.println("Message processed ");
}
}
}
The difference between synchronized(this) and synchronized(m) is that by synchronizing on this, you synchronize on the entire instance. So, as you would expect, no body would be able to synchronize on this while you hold the lock.
public synchronized void foo() {
// Handle shared resource
}
is similar to
public void foo() {
synchronize(this) {
// Handle shared resource
}
}
By using objects, such as m, you get a more fine grained control over what you want to synchronize and when. But remember that if someone uses foo(), as shown above, it will not stop access to methods that are not synchronized on this:
public void anotherLock() {
synchronized(m) {
// Should handle another shared resource
// otherwise you might get unexpected results
}
}
While a thread is using foo(), another thread can access anotherLock().
The java keyword synchronized is used to synchronize different threads by one instance, acting as a mutual exclusive semaphore. Hence, the argument passed to synchronized is the instance which can be owned by one thread exclusively. It is up to you, the programmer, on which instance you like to synchronize your threads.
But it is a good idea to use the resource, which is under racing conditions, or the owning instance of that resource. The later you start a synchronized block and the earlier you leave it, the better your application will scale.
synchronized is used for thread safety. In your case it is used for implementing observer pattern. you want to wait for something to happen on Message object and then only process it so someone will notify on Message object m for which you are waiting (m.wait()).
When you wait on some object you need to take lock on that object for which you always need to put the wait() statement in a synchronized block on wait object. That is why you are using synchronized(m).
You can not replace it with synchronized(this) as you are calling wait() on object m so synchronized should be on m only.
Somewhere in your application you must be calling m.notify() or m.notifyAll() which will resume your wait() on m.

Java synchronized keyword - Does it protect a class method from being executed at the same time?

I need some clarificaton on how the syncronized keyword works in java 6.
Using the following example class.
class Carrier {
private String[] _collection = new String[2];
public Carrier() {
this._collection[0] = "abc";
this._collection[1] = "123";
}
public syncronized void change(int cId) {
Thread.sleep(3000);
this._collection[cId] = "changed";
}
}
Now, some place in the application, referencing the same object instance of the Carrier class, the .change() method is called, possibly at the same time.
...carrier.change(1);
...
...carrier.change(1);
Will the syncronized keyword prevent asyncronized execution of the method? Will it simply queue the call to .change(), waiting for each one to complete?
Yes, the second thread will block while the first thread is executing. That's because they both try to acquire the monitor on the same object - via this, in this case. So your change method is equivalent to:
public void change(int cId) {
synchronized (this) {
Thread.sleep(3000);
this._collection[cId] = "changed";
}
}
Personally I don't like synchronizing on "this" as it means any other code with access to the object itself could acquire the same monitor. I prefer to create an object just for locking which only code within the class has access to:
private final Object lock = new Object();
public void change(int cId) {
synchronized (lock) {
Thread.sleep(3000);
this._collection[cId] = "changed";
}
}
That will still have the same effect in terms of two threads calling change on the same object, because both threads will still be acquiring the same monitor - just the one associated with the lock-specific object.
Yes, it will prevent the two method calls from executing at the same time.
That is really what the main use of the synchronized keyword is.
When one synchronized method runs, it obtains a 'lock' on the object it is called on. That means no other synchronized code can be run on that object while that method holds the lock. Once the method is done executing, it will release the lock, and other synchronized methods can obtain a lock on that object.
Yes, and yes. (Note that it's synchronized, not syncronized)
Yes - the synchronized keyword prevents simultaneous execution of the method by different threads.
Note: A "class method" is a static method. An "instance method" (ie non-static) is what you have in your question.
synchronized are used for preventing simultaneously accesses in cuncurrent programming.
For example when you have to client, one that reads and another that writes:
Lock here for an exhaustive explanation.

My Long pending confusion on multi-threading in Java. Need help

I am having this doubt about multi-threading and I have faced lots of questions about in multi-threading in many of the interviews.
I speak a lot of about acquiring a lock on the object as such. My doubt is when you have two methods that are synchronized and there are two threads which wants to access those two methods, ThreadA wants to access MethodA and ThreadB wants to access MethodB.
Now both the methods are in the same object. But I use to say acquiring lock on an object and i have not heard acquiring lock on a method. Now Can both the threads parallely access MethodA and MethodB? My assumption is once you acquire lock on object, no other thread on work on it. Isnt it?
And what is the significance synchronized(XYZ.class)?
No, they cannot. If I understand you correctly then you mean:
class Foo {
public synchronized void methodA () {
doSmth ();
}
public synchronized void methodB () {
doSmthElse ();
}
}
In this case synchronized modifier is equal to:
class Foo {
public void methodA () {
synchronized (this) {
doSmth ();
}
}
public void methodB () {
synchronized (this) {
doSmthElse ();
}
}
}
This means that only 1 thread can work at the same time inside one of these 2 methods on each Foo-object.
And what is the significance synchronized(XYZ.class)?
That's what you have behind the scenes of
class XYZ {
public static synchronized void someMethod () { ... }
}
Declaring a method as synchronized is basically the same as containing the entire method body in a "synchronized(this) { ... }" block. So the lock on synchronized method is on the entire object instance, meaning that you are locking out others who want to use synchronized methods on that same object.
If you want per method synchronization instead of per object synchronization you will have to synchronize on something else, either by using synchronized(guardObject) in that particular method or by using one of the Lock objects in java (most of them added in 1.5).
And what is the significance synchronized(XYZ.class)?
This means that you are using the class as a guard object, it means that the lock in the class itself (not the instance) will be protecting access to the block. The difference to using the object instance as a guard is that if you have ten thousand objects you will only be able to access one of them at a time, compared to protecting access by more than one thread to an instance at a time.
If methodA and methodB use different data structures, and it's safe to call methodA while somebody else is calling methodB, then those two methods should use different locks.
Here's the skinny on synchronized(XYZ.class)
synchronized (XYZ.class) is how you implment the above pattern -- it's a synchronized block that:
acquires a lock on an object (in this class the instance of java.lang.class that represents XYZ)
does some work
releases the lock.
The key is to remember that every object in Java has a lock (the technical term is a monitor) that can be held by only one thread at a time. You can request the lock for any object that you have a reference to.
The synchronized keyword on a method:
public synchronized void foo() {
//do something
}
is just syntactic sugar for this:
public void foo() {
synchronized(this) {
//do something
}
}
There is one significant drawback to this approach: since anyone with a reference to an object can acquire its lock, synchronized methods won't work properly if an external caller acquires and holds the object lock.
(Incidentally, this is why locking on XYZ.class is also a bad idea: it's a globally accesible object, and you never know who might decide to acquire its lock)
To avoid these drawbacks, this pattern is usually used instead of the synchronized method:
private final Object LOCK = new Object();
public void foo() {
synchronized(LOCK) {
//do something
}
}
Since no external caller can have a reference to the LOCK object, only this class can acquire its lock, and the synchronized method will always work as expected.
When you have two different methods that need to be locked separately, the usual way to do that is for each method to lock on a different privately held object:
private final Object LOCKA = new Object();
private final Object LOCKB = new Object();
public void foo() {
synchronized(LOCKA) {
//do something
}
}
public void bar() {
synchronized(LOCKB) {
//do something else
}
}
Then it's possible for a thread to call foo() while another thread is calling bar(), but only one thread will be able to call foo() at a time, and only one thread will be able to call bar() at a time.
Using synchronized(XYZ.class) is very restrictive. This means whatever code is being guarded by this XYZ.class will be executed by one thread only at the same time. You should be aware of this as it could lead to severe starvation problem.
A thread entering into monitor on entrance to critical section defined as 'synchronized'
So you can define each method (not the whole class) as synchronized or even a code block within a method.
http://java.sun.com/docs/books/tutorial/essential/concurrency/locksync.html

Categories

Resources