I have a class ClassA that has a public void doSomething() method. This ClassA is widely used in different applications; some require synchronized and others do not. It is also the case that I do not want the (tiny, but non-zero) performance hit associated with calling a synchronized method when I do not need this.
Suppose that ClassB will call doSomething() and requires that this is synchronized, yet ClassC does not require this. What are the ways that I can achieve this in the design of my program?
Is it sufficient to have the method in ClassB:
private synchronized void doSomething() {
this.classAInstance.doSomething();
}
thus avoiding the need to specify ClassC's doSomething() as synchronized?
When you have a need to use the same class with and without synchronization, a common approach is to make an interface, and provide two implementations - a non-synchronized class with the actual implementation, and a thin wrapper that adds synchronization.
Here is a simple example: suppose you are building a class with two operations - getSomething and setSomething. The interface may look like this:
interface Demo {
void setSomething(Something value);
Something getSomething();
}
Now the non-synchronized implementation may look like this:
class DemoImpl implements Demo {
private Something theSomething;
public void setSomething(Something value) {
theSomething = value;
}
public Something getSomething() {
return theSomething;
}
}
Finally, the synchronized implementation:
class SyncDemoImpl implements Demo {
private DemoImpl impl = new DemoImpl();
public synchronized void setSomething(Something value) {
impl.setSomething(value);
}
public synchronized Something getSomething() {
return impl.getSomething();
}
}
Bear in mind that this is purely an academical exercise. I don't see any practical reason why a resource should need a selective synchronized access. Either you need it, or you don't. If you have to do this, you are setting yourself up for long hours of troubleshooting few months down the line. If I could, I would rethink the design.
So,
You say - 'some require synchronized and others do not'
I take that means you know exactly each and every part of your code that needs Synchronized access, and can differentiate it from those that need to save this overhead. If so: You have two options:
Get rid of the synchronized modifier of the method all together and get all the callers that need synchronization to synchronize before the call is made. Thus:
synchronized (classAInstance){
classAInstance.doSomething(); // the doSomething() is non-synchronised
}
Those parts in code that call this method and do not need synchronized access can call the method directly.
Make two methods, one that is synchronized and other that is not synchronized. Change the callers to call based on the way you want the access to be controlled.
Related
Difference between the two synchronized blocks in the doThis method:
Which should be used when?
public class AClass {
private final Object lock = new Object();
public void doThis(){
synchronized(lock){
//do stuff
}
}
}
and
public class BClass {
public void doThis(){
synchronized(this){
//do stuff
}
}
}
When should one be used over the other?
Always use the first one.
If you do synchronized (this), you are synchronizing on an object that any other code also has the ability to synchronize on, and thus unwittingly mess up your class’s ability to function.
If you synchronize on a private object, absolutely no one can synchronize on it except the code in your class. No one has the power to interfere with your functionality.
The reason to use a lock object, rather than this, is simply to give yourself flexibility and to avoid deadlocks. Note that these two reasons only come into play if different methods need to synchronize, and not against each other. Providing two lock objects then makes sense. Most of the time, just using this is fine.
I was wondering if there is a situation where this statement will be true and needed. All the examples I have seen only synchronize on the "this" reference. Can someone tell me how a block of code in one object can be synchronized on any other reference apart from this ?
Yes the statement is true.
There are several reasons why one would want NOT to use an intrinsic monitor (synchronized(this)) - one of these reasons is that it can create liveness issues - in the code below, B uses an instance of A as a lock, maybe to control access to that variable. If another thread uses that same instance of A and tries to run a.methodA(), it will be blocked until methodB() is over.
So using an intrinsic monitor exposes the synchronization policy and can lead to subtle bugs and performance issues.
public class A {
public synchronized void methodA() {}
}
public class B {
A a = new A();
public void methodB() {
synchronized(a) {
// do something a little long
}
}
public A getA() {return a;}
}
If A had used an internal monitor that problem would not be possible.
public class A {
private final Object lock = new Object();
public void methodA() {
synchronized(lock) {}
}
}
Another scenario where using ad hoc monitors makes sense is when a class contains 2 (or more) unrelated objects, that both need to be accessed in a synchronized manner. Using 2 monitors instead of one reduces contention as the 2 objects can now be accessed concurrently.
public class SyncTest{
private Object obj = new Object();
public void func1() {
synchronized(obj) {
obj.something();
}
}
Yes it can be done.
The synchronize block will use that object as a lock, rather than the whole class. People that use synchronized(this) { } put an exclusive lock on the whole object, which might be what you want. However, you might have something like a persister, which is the only thing that needs to be synchronized. synchronized(persister) { }, would provide a less granular way of doing this.
In Java, you can use synchronized constructs to create instrinsic locks on any object reference, yes. Read the relevant Java Tutorial.
The immediate example of not using synchronized with this is when synchronizing on the Class object, which is how static synchronized methods work. In reality, there are plenty of valid uses. You may want to avoid using synchronized (this) in favor of an internal implementation lock as otherwise you are setting a restriction that you use the lock internally, which other code you're not aware of might violate.
You should know, however, that often times you can replace synchronized usage with a ReentrantLock. You can read more about this in my post here.
Suppose I have a Utility class,
public class Utility {
private Utility() {} //Don't worry, just doing this as guarantee.
public static int stringToInt(String s) {
return Integer.parseInt(s);
}
};
Now, suppose, in a multithreaded application, a thread calls, Utility.stringToInt() method and while the operation enters the method call, another thread calls the same method passing a different s.
What happens in this case? Does Java lock a static method?
There is no issue here. Each thread will use its own stack so there is no point of collision among different s. And Integer.parseInt() is thread safe as it only uses local variables.
Java does not lock a static method, unless you add the keyword synchronized.
Note that when you lock a static method, you grab the Mutex of the Class object the method is implemented under, so synchronizing on a static method will prevent other threads from entering any of the other "synchronized" static methods.
Now, in your example, you don't need to synchronize in this particular case. That is because parameters are passed by copy; so, multiple calls to the static method will result in multiple copies of the parameters, each in their own stack frame. Likewise, simultaneous calls to Integer.parseInt(s) will each create their own stack frame, with copies of s's value passed into the separate stack frames.
Now if Integer.parseInt(...) was implemented in a very bad way (it used static non-final members during a parseInt's execution; then there would be a large cause for concern. Fortunately, the implementers of the Java libraries are better programmers than that.
In the example you gave, there is no shared data between threads AND there is no data which is modified. (You would have to have both for there to be a threading issue)
You can write
public enum Utility {
; // no instances
public synchronized static int stringToInt(String s) {
// does something which needs to be synchronised.
}
}
this is effectively the same as
public enum Utility {
; // no instances
public static int stringToInt(String s) {
synchronized(Utility.class) {
// does something which needs to be synchronised.
}
}
}
however, it won't mark the method as synchronized for you and you don't need synchronisation unless you are accessing shared data which can be modified.
It should not unless specified explicitly. Further in this case, there wont be any thread safety issue since "s" is immutable and also local to the method.
You dont need synchronization here as the variable s is local.
You need to worry only if multiple threads share resources, for e.g. if s was static field, then you have to think about multi-threading.
My doubt is do we need to make static methods as synchronized if it is called within synchonized non static method?
for e.g.
class Test
{
public static void m2()
{
}
public synchronized void m1()
{
Test.m2();
----
----
}
In above case do I need to make m2 as synchronized in order to avoid race condition or should I keep it as it is.
}
It depends on what your static method is doing. Do you really need it to be synchronized at all? Is it accessing shared mutable state?
If so, you probably do need to synchronize (although I wouldn't do so just with the synchronized modifier - I'd create a private static final variable with an object to lock on.)
The fact that your instance method is synchronized means that no two threads will be executing it with the same target object - but two threads could both be executing m1 with different target objects, so m2 could be called twice at the same time. Whether that's a problem or not depends on what it's doing. If it's not using any shared state (e.g. it's really just computing something based on its parameters) then it doesn't need to be synchronized at all.
Generally speaking, it's more important for static methods to be thread-safe than instance methods: I typically don't make types themselves thread-safe, but instead try to use a few classes to manage concurrency, with each thread using its own set of separate objects as far as possible.
You do need to make m2 synchronized. Otherwise someone can call that method at the same time. I am assuming m2 would be considered for being synchronized, otherwise it is a moot point.
generally it could be usefull to synchronize a static method. For example in this case:
private static final List<Object> GLOBAL_STATE = new ArrayList<Object>();
public static synchronized void add(Object foo) {
GLOBAL_STATE.add(foo);
}
But in your case you call the method from another already synchronized method. So you don't have to synchronize it. But in your example you make your static method public. If this was intended, make it synchronized too.
In what cases is it necessary to synchronize access to instance members?
I understand that access to static members of a class always needs to be synchronized- because they are shared across all object instances of the class.
My question is when would I be incorrect if I do not synchronize instance members?
for example if my class is
public class MyClass {
private int instanceVar = 0;
public setInstanceVar()
{
instanceVar++;
}
public getInstanceVar()
{
return instanceVar;
}
}
in what cases (of usage of the class MyClass) would I need to have methods:
public synchronized setInstanceVar() and
public synchronized getInstanceVar() ?
Thanks in advance for your answers.
The synchronized modifier is really a bad idea and should be avoided at all costs. I think it is commendable that Sun tried to make locking a little easier to acheive, but synchronized just causes more trouble than it is worth.
The issue is that a synchronized method is actually just syntax sugar for getting the lock on this and holding it for the duration of the method. Thus, public synchronized void setInstanceVar() would be equivalent to something like this:
public void setInstanceVar() {
synchronized(this) {
instanceVar++;
}
}
This is bad for two reasons:
All synchronized methods within the same class use the exact same lock, which reduces throughput
Anyone can get access to the lock, including members of other classes.
There is nothing to prevent me from doing something like this in another class:
MyClass c = new MyClass();
synchronized(c) {
...
}
Within that synchronized block, I am holding the lock which is required by all synchronized methods within MyClass. This further reduces throughput and dramatically increases the chances of a deadlock.
A better approach is to have a dedicated lock object and to use the synchronized(...) block directly:
public class MyClass {
private int instanceVar;
private final Object lock = new Object(); // must be final!
public void setInstanceVar() {
synchronized(lock) {
instanceVar++;
}
}
}
Alternatively, you can use the java.util.concurrent.Lock interface and the java.util.concurrent.locks.ReentrantLock implementation to achieve basically the same result (in fact, it is the same on Java 6).
It depends on whether you want your class to be thread-safe. Most classes shouldn't be thread-safe (for simplicity) in which case you don't need synchronization. If you need it to be thread-safe, you should synchronize access or make the variable volatile. (It avoids other threads getting "stale" data.)
If you want to make this class thread safe I would declare instanceVar as volatile to make sure you get always the most updated value from memory and also I would make the setInstanceVar() synchronized because in the JVM an increment is not an atomic operation.
private volatile int instanceVar =0;
public synchronized setInstanceVar() { instanceVar++;
}
. Roughly, the answer is "it depends". Synchronizing your setter and getter here would only have the intended purpose of guaranteeing that multiple threads couldn't read variables between each others increment operations:
synchronized increment()
{
i++
}
synchronized get()
{
return i;
}
but that wouldn't really even work here, because to insure that your caller thread got the same value it incremented, you'd have to guarantee that you're atomically incrementing and then retrieving, which you're not doing here - i.e you'd have to do something like
synchronized int {
increment
return get()
}
Basically, synchronization is usefull for defining which operations need to be guaranteed to run threadsafe (inotherwords, you can't create a situation where a separate thread undermines your operation and makes your class behave illogically, or undermines what you expect the state of the data to be). It's actually a bigger topic than can be addressed here.
This book Java Concurrency in Practice is excellent, and certainly much more reliable than me.
To simply put it, you use synchronized when you have mutliple threads accessing the same method of the same instance which will change the state of the object/or application.
It is meant as a simple way to prevent race conditions between threads, and really you should only use it when you are planning on having concurrent threads accessing the same instance, such as a global object.
Now when you are reading the state of an instance of a object with concurrent threads, you may want to look into the the java.util.concurrent.locks.ReentrantReadWriteLock -- which in theory allows many threads to read at a time, but only one thread is allowed to write. So in the getter and setting method example that everyone seems to be giving, you could do the following:
public class MyClass{
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private int myValue = 0;
public void setValue(){
rwl.writeLock().lock();
myValue++;
rwl.writeLock().unlock();
}
public int getValue(){
rwl.readLock.lock();
int result = myValue;
rwl.readLock.unlock();
return result;
}
}
In Java, operations on ints are atomic so no, in this case you don't need to synchronize if all you're doing is 1 write and 1 read at a time.
If these were longs or doubles, you do need to synchronize because it's possible for part of the long/double to be updated, then have another thread read, then finally the other part of the long/double updated.