my code uses the following:
public class Obj{
public String someOperation(){...}
};
public class ClassA{
private Map<Integer, Object> m_MsgHash;
public boolean init()
{
m_MsgHash = Collections.synchronizedMap(new LinkedHashMap<Integer, Object>(1001, 1.0F, true));
}
private Object fetchFromHash(int Id)
{
return m_MsgHash.get(Id);
}
public void HandleMsg(int Id)
{
Object obj = fetchFromHash(Id);
// do some operation on obj needs to be synchronized ?
//synchronized (m_MsgHash) {
obj.someOperation();
//}
}
}
I understand from Java Doc that once iterating the my m_MsgHash i must use the synchronized keyword. but my question is, do i need to use the synchronized when using a fetched Object from my map ?
You do not need "synchronized" for simple operations on a synchronizedMap result, such as get. If the object referenced by obj is itself accessed from multiple threads, and modified by at least one of them, you need to make all accesses to it synchronized on the same object, or otherwise ensure multi-thread correctness.
No you don't: m_MsgHash.get(Id); is synchronized so it is a thread safe operation. And once you have a reference to obj you can do whatever you want with it without needing to synchronize as it lives independently from the map (as long as you don't share it across threads, but here it is a local variable).
Note however that your map is not safely published as it is. If a thread calls init and another calls HandleMsg, it is possible that the second thread sees a null value for the map.
A simple way to safely publish the map would be to make it final and instantiate it within the constructor of ClassA.
Not required. Whenever you call Collections.synchronizedMap It creates a class that implements Map interface and has all the methods synchronized. This is called Java Monitor Pattern, where the underlying LinkedHashMap is protected by a Java Monitor to enable thread safety. You need to synchronize while looping because the Map may change while looping through.
But actions like put, get and remove are protected by the class Monitor thus not required to be inside of synchronized methods, unless they are part of a composite action such as Check-Then-Act.
Related
I want to know how to use synchronized blocks across classes. What I mean is, I want to have synchronized blocks in more than one class but they're all synchronizing on the same object. The only way that I've thought of how to do this is like this:
//class 1
public static Object obj = new Object();
someMethod(){
synchronized(obj){
//code
}
}
//class 2
someMethod(){
synchronized(firstClass.obj){
//code
}
}
In this example I created an arbitrary Object to synchronize on in the first class, and in the second class also synchronized on it by statically referring to it. However, this seems like bad coding to me.
Is there a better way to achieve this?
Having a static object that is used as a lock typically is not desirable because only one thread at a time in the whole application can make progress. When you have multiple classes all sharing the same lock that's even worse, you can end up with a program that has little to no actual concurrency.
The reason Java has intrinsic locks on every object is so that objects can use synchronization to protect their own data. Threads call methods on the object, if the object needs to be protected from concurrent changes then you can add the synchronized keyword to the object's methods so that each calling thread must acquire the lock on that object before it can execute a method on it. That way calls to unrelated objects don't require the same lock and you have a better chance of having code actually run concurrently.
Locking shouldn't necessarily be your first go-to technique for concurrency. Actually there are a number of techniques you can use. In order of descending preference:
1) eliminate mutable state wherever possible; immutable objects and stateless functions are ideal because there's no state to protect and no locking required.
2) use thread-confinement where you can; if you can limit state to a single thread then you can avoid data races and memory visibility issues, and minimize the amount of locking.
3) use concurrency libraries and frameworks in preference to rolling your own objects with locking. Get acquainted with the classes in java.util.concurrent. These are a lot better written than anything an application developer can manage to throw together.
Once you've done as much as you can with 1, 2, and 3 above, then you can think about using locking (where locking includes options like ReentrantLock as well as intrinsic locking). Associating the lock with the object being protected minimizes the scope of the lock so that a thread doesn't hold the lock longer than it needs to.
Also if the locks aren't on the data being locked then if at some point you decide to use different locks rather than having everything lock on the same thing, then avoiding deadlocks may be challenging. Locking on the data structures that need protecting makes the locking behavior easier to reason about.
Advice to avoid intrinsic locks altogether may be premature optimization. First make sure you're locking on the right things no more than necessary.
OPTION 1:
More simple way would be to create a separate object (singleton) using enum or static inner class. Then use it to lock in both the classes, it looks elegant:
// use any singleton object, at it's simplest can use any unique string in double quotes
public enum LockObj {
INSTANCE;
}
public class Class1 {
public void someMethod() {
synchronized (LockObj.INSTANCE) {
// some code
}
}
}
public class Class2 {
public void someMethod() {
synchronized (LockObj.INSTANCE) {
// some code
}
}
}
OPTION:2
you can use any string as JVM makes sure it's only present once per JVM. Uniqueness is to make sure no-other lock is present on this string. Don't use this option at all, this is just to clarify the concept.
public class Class1 {
public void someMethod() {
synchronized ("MyUniqueString") {
// some code
}
}
}
public class Class2 {
public void someMethod() {
synchronized ("MyUniqueString") {
// some code
}
}
}
Your code seems valid to me, even if it does not look that nice. But please make your Object you are synchronizing on final.
However there could be some considerations depending on your actual context.
In any way should clearly state out in the Javadocs what you want to archive.
Another approach is to sync on FirstClass e.g.
synchronized (FirstClass.class) {
// do what you have to do
}
However every synchronized method in FirstClass is identical to the synchronized block above. With other words, they are also synchronized on the same object. - Depending on the context it may be better.
Under other circumstances, maybe you'd like to prefer some BlockingQueue implementation if it comes down that you want to synchronize on db access or similar.
I think what you want to do is this. You have two worker classes that perform some operations on the same context object. Then you want to lock both of the worker classes on the context object.Then the following code will work for you.
public class Worker1 {
private final Context context;
public Worker1(Context context) {
this.context = context;
}
public void someMethod(){
synchronized (this.context){
// do your work here
}
}
}
public class Worker2 {
private final Context context;
public Worker2(Context context) {
this.context = context;
}
public void someMethod(){
synchronized (this.context){
// do your work here
}
}
}
public class Context {
public static void main(String[] args) {
Context context = new Context();
Worker1 worker1 = new Worker1(context);
Worker2 worker2 = new Worker2(context);
worker1.someMethod();
worker2.someMethod();
}
}
I think you are going the wrong way, using synchronized blocks at all. Since Java 1.5 there is the package java.util.concurrent which gives you high level control over synchronization issues.
There is for example the Semaphore class, which provides does some base work where you need only simple synchronization:
Semaphore s = new Semaphore(1);
s.acquire();
try {
// critical section
} finally {
s.release();
}
even this simple class gives you a lot more than synchronized, for example the possibility of a tryAcquire() which will immediately return whether or not a lock was obtained and leaves to you the option to do non-critical work until the lock becomes available.
Using these classes also makes it clearer, what prupose your objects have. While a generic monitor object might be misunderstood, a Semaphore is by default something associated with threading.
If you peek further into the concurrent-package, you will find more specific synchronisation-classes like the ReentrantReadWriteLock which allows to define, that there might be many concurrent read-operations, while only write-ops are actually synchronized against other read/writes. You will find a Phaser which allows you to synchronize threads such that specific tasks will be performed synchronously (sort of the opposite of synchornized) and also lots of data structures which might make synchronization unnecessary at all in certain situations.
All-in-all: Don't use plain synchronized at all unless you know exactly why or you are stuck with Java 1.4. It is hard to read and understand and most probably you are implementing at least parts of the higher functions of Semaphore or Lock.
For your scenario, I can suggest you to write a Helper class which returns the monitor object via specific method. Method name itself define the logical name of the lock object which helps your code readability.
public class LockingSupport {
private static final LockingSupport INSTANCE = new LockingSupport();
private Object printLock = new Object();
// you may have different lock
private Object galaxyLock = new Object();
public static LockingSupport get() {
return INSTANCE;
}
public Object getPrintLock() {
return printLock;
}
public Object getGalaxyLock() {
return galaxyLock;
}
}
In your methods where you want to enforce the synchronization, you may ask the support to return the appropriate lock object as shown below.
public static void unsafeOperation() {
Object lock = LockingSupport.get().getPrintLock();
synchronized (lock) {
// perform your operation
}
}
public void unsafeOperation2() { //notice static modifier does not matter
Object lock = LockingSupport.get().getPrintLock();
synchronized (lock) {
// perform your operation
}
}
Below are few advantages:
By having this approach, you may use the method references to find all places where the shared lock is being used.
You may write the advanced logic to return the different lock object(e.g. based on caller's class package to return same lock object for all classes of one package but different lock object for classes of other package etc.)
You can gradually upgrade the Lock implementation to use java.util.concurrent.locks.LockAPIs. as shown below
e.g. (changing lock object type will not break existing code, thought it is not good idea to use Lock object as synchronized( lock) )
public static void unsafeOperation2() {
Lock lock = LockingSupport.get().getGalaxyLock();
lock.lock();
try {
// perform your operation
} finally {
lock.unlock();
}
}
Hopes it helps.
First of all, here are the issues with your current approach:
The lock object is not called lock or similar. (Yes ... a nitpick)
The variable is not final. If something accidentally (or deliberately) changes obj, your synchronization will break.
The variable is public. That means other code could cause problems by acquiring the lock.
I imagine that some of these effects are at the root of your critique: "this seems like bad coding to me".
To my mind, there are two fundamental problems here:
You have a leaky abstraction. Publishing the lock object outside of "class 1" in any way (as a public or package private variable OR via a getter) is exposing the locking mechanism. That should be avoided.
Using a single "global" lock means that you have a concurrency bottleneck.
The first problem can be addressed by abstracting out the locking. For example:
someMethod() {
Class1.doWithLock(() -> { /* code */ });
}
where doWithLock() is a static method that takes a Runnable or Callable or similar, and then runs it with an appropriate lock. The implementation of doWithLock() can use its own private static final Object lock ... or some other locking mechanism according to its specification.
The second problem is harder. Getting rid of a "global lock" typically requires either a re-think of the application architecture, or changing to a different data structures that don't require an external lock.
I am curios about something to do with Java Method Synchronization and Object locking.
When you invoke a synchronized method, from what i understand it locks the entire object for the duration of the method call.
Does this mean you only need to synchronize methods that write data to your object and not for the reading of data from your object?
public class testclass {
private ArrayList<String> data;
public ArrayList<String> getData() {
return data;
}
public synchronized void setData(ArrayList<String> data) {
this.data = data;
}
}
Basically would the above code be thread safe (Since the testclass object is locked while running the setData method)? or should i also synchronize the getData method as well?
Does this mean you only need to synchronize methods that write data to your object and not for the reading of data from your object?
No - if you don't synchronize the reads, you don't have any visibility guarantee (you could get a stale version of the object).
Note: in your case, you don't need to use the synchronized keyword because each method is atomic - you could simply make data volatile instead.
locks are not locking object itself, but monitor associated with object. In your case even synchronization of method getData doesn't make testclass thread safe, because it will return instance of "data" field to wild world, and many threads may do whatever they want with object in unpredictable order.
in order to follow "visibility", you either need to make "data" volatile, or synchronize both methods - because JVM is free to optimize bytecode in any way, which makes it possible for some threads to see "stale" data.
If you don't synchronize getData() method what guarantee do you have that when one thread first invokes getData() first and another thread wants to execute writeData() method, the thread is not locked. Hence not thread safe.
[EDIT]
And as other specified, it is not thread safe for you to return the non-volatile Data object too, which might be modified in a non-thread-safe-way outside this class
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.
I'm trying to learn about singleton classes and how they can be used in an application to keep it thread safe. Let's suppose you have an singleton class called IndexUpdater whose reference is obtained as follows:
public static synchronized IndexUpdater getIndexUpdater() {
if (ref == null)
// it's ok, we can call this constructor
ref = new IndexUpdater();
return ref;
}
private static IndexUpdater ref;
Let's suppose there are other methods in the class that do the actual work (update indicies, etc.). What I'm trying to understand is how accessing and using the singleton would work with two threads. Let's suppose in time 1, thread 1 gets a reference to the class, through a call like this IndexUpdater iu = IndexUpdater.getIndexUpdater(); Then,
in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton or would it be prevented as long as the first thread has an active reference to the class. I'm assuming the latter (or else how would this work?) but I'd like to make sure before I implement.
Thank you,
Elliott
Since getIndexUpdater() is a synchronized method, it only prevents threads from accessing this method (or any method protected by the same synchronizer) simultaneously. So it could be a problem if other threads are accessing the object's methods at the same time. Just keep in mind that if a thread is running a synchronized method, all other threads trying to run any synchronized methods on the same object are blocked.
More info on:
http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Your assumption is wrong. Synchronizing getIndexUpdater() only prevents more than one instance being created by different threads calling getIndexUpdater() at (almost) the same time.
Without synchronization the following could happen: Thread one calls getIndexUpdater(). ref is null. Thread 2 calls getIndexUpdater(). ref is still null. Outcome: ref is instantiated twice.
You are conflating the instantiation of a singleton object with its use. Synchronizing the creation of a singleton object does not guarantee that the singleton class itself is thread-safe. Here is a simple example:
public class UnsafeSingleton {
private static UnsafeSingleton singletonRef;
private Queue<Object> objects = new LinkedList<Object>();
public static synchronized UnsafeSingleton getInstance() {
if (singletonRef == null) {
singletonRef = new UnsafeSingleton();
}
return singletonRef;
}
public void put(Object o) {
objects.add(o);
}
public Object get() {
return objects.remove(o);
}
}
Two threads calling getInstance are guaranteed to get the same instance of UnsafeSingleton because synchronizing this method guarantees that singletonRef will only be set once. However, the instance that is returned is not thread safe, because (in this example) LinkedList is not a thread-safe queue. Two threads modifying this queue may result in unexpected behavior. Additional steps have to be taken to ensure that the singleton itself is thread-safe, not just its instantiation. (In this example, the queue implementation could be replaced with a LinkedBlockingQueue, for example, or the get and put methods could be marked synchronized.)
Then, in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton ...?
The answer is yes. Your assumption on how references are obtained is wrong. The second thread can obtain a reference to the Singleton. The Singleton pattern is most commonly used as a sort of pseudo-global state. As we all know, global state is generally very difficult to deal with when multiple entities are using it. In order to make your singleton thread safe you will need to use appropriate safety mechanisms such as using atomic wrapper classes like AtomicInteger or AtomicReference (etc...) or using synchronize (or Lock) to protect critical areas of code from being accessed simultaneously.
The safest is to use the enum-singleton.
public enum Singleton {
INSTANCE;
public String method1() {
...
}
public int method2() {
...
}
}
Thread-safe, serializable, lazy-loaded, etc. Only advantages !
When a second thread tries to invoke getIndexUpdater() method, it will try to obtain a so called lock, created for you when you used synchronized keyword. But since some other thread is already inside the method, it obtained the lock earlier and others (like the second thread) must wait for it.
When the first thread will finish its work, it will release the lock and the second thread will immediately take it and enter the method. To sum up, using synchronized always allows only one thread to enter guarded block - very restrictive access.
The static synchronized guarantees that only one thread can be in this method at once and any other thread attempting to access this method (or any other static synchronized method in this class) will have to wait for it to complete.
IMHO the simplest way to implement a singleton is to have a enum with one value
enum Singleton {
INSTANCE
}
This is thread safe and only creates the INSTANCE when the class is accessed.
As soon as your synchronized getter method will return the IndexUpdater instance (whether it was just created or already existed doesn't matter), it is free to be called from another thread. You should make sure your IndexUpdater is thread safe so it can be called from multiple threads at a time, or you should create an instance per thread so they won't be shared.
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.