Java synchronization problem - java

I have two threads and one class.
Thread1 updates the local object of the class via 3 different methods.
The local object (behind the scene) uses some sort of ArrayList to store data.
Three methods (mentioned earlier), are doing something with elements of the list...
Thread2 queries the local object (content of array list).
PROBLEM:
How can I make sure that none of the three updating methods (Thread1) will modify the content of the "local object" while it's being read by Thread2?
Thanks

Put a common lock around portions of the code that modify the ArrayList using synchronized. It doesn't really matter what object you use as a lock, as long as it's the same, but I think using the ArrayList itself would be idiomatic:
synchronized (list) {
list.put()...
}
synchronized (list) {
list.get()...
}

You can make the methods which access the data (read or write) 'synchronized'.

In all methods mentionned above use a synchronized(your_list) { ... code ... } context, making the methods synchronized is a maybe to hard solution, blocks more than needed if you just want to protect the list and not the whole object.

Using synchronized keyword. You are dealing with problem known as critical sections

I suggest you read the Java Tutorial on Concurrency, in particular the section on synchronization. You have a straightforward case of synchronization.

Related

how to locally synchronize two maps?

For instance,
class Test{
static Map a = new ...
static Map b = new ...
public void process(){
...
a.put(...);
b.put(...);
}
}
Do I have to lock like this:
synchronized(a){
a.put();
}
synchronized(b){
b.put(b);
}
This seems to be awkward. Any other right way to do this? Thanks.
No, you need both operations in one synchronized block, otherwise another thread may see inconsistencies between the two maps.
One possible option would be using a synchronized method, or you could use some other private object or one of the maps as an monitor. Here is the synchronized method example:
static Map a = new ...
static Map b = new ...
public synchronized void process(){
...
a.put(...);
b.put(...);
}
}
You can use a dedicated object like
Object mapLock = new Object();
to synchronize on.
Or you can sync on a keeping in mind that even if you need an access to b you need to sync on a.
Synchronizing on this is not a good idea in general. I mean this is a bad habit and doing so may eventually result in bad performance or non-obvious deadlocks if not in this but other applications you make.
Avoid synchronized(this) in Java?
You can also consider using ReadWriteLock from concurrency package.
You do need to run both operations within one synchronized block. Worth noting that in your example, you've defined the maps statically while the process() method is an instance method. The synchronizing the method will mean that calls to that instance will be synchronized, but that calls to 2 different instances will not (as the lock used when applying the synchronized keyword to a method is effectively this). You could either make the process() method static, or use a synchronized(Test.class) {} block instead to ensure that there's no racing happening.
You will also need to be careful about how you expose the maps to clients - if you're offering them up as properties, then I would probably wrap them with Collections.unmodifiableMap() to ensure that nothing else can go and screw with them while you're not looking - however that doesn't entirely protect against clients having an "odd" time as they will still see changes happen in potentially unsafe ways. As such, I'd also probably declare the types as ConcurrentHashMap to make things a little safer (although there are still some dangerous operations such as sharing an Iterator between threads)

mutual exclusion using Hashtable of java

hi mate i have a global Hashtable in my class, and two thread A and B that work with her.
A reads from HashTable and B write in Hashtable.. is there a problem of mutual exclusion ? i need to syncrhonize it or Hashtable class is safe ?
Hashtable is a thread-safe implementation of the Map interface.
In regular put and get operations you will be safe. However, when you will iterate on it in one thread and modify its contents from another thread, you will have ConcurrentModificationException issues. So, when iterating, make sure you iterate on a copy of the original Hashtable.
You should use ConcurrentHashMap instead, which is a much better/faster implementation of java.util.Map interface.
It's useful to use a synchronized HashMap offered by java collections. This class is a simple wrapper and encapsulates the hashmap :
Collections.synchronizedMap(new HashMap());
Further example example is in the java docs :
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html synchronizedMap
HashTable gaurantees that any operation executed on it is atomic. but If you are executing multiple operations you should synchronize them. In below example even if contains and put are atomic but the code has a check and act raise condition so you need additional synchronization for this.
if(!hashtable.contains(Object))
{
hashtable.put(key, value);
}
Also check Collections.synchronizedMap() or ConcurrentHashMap rather than HashTable
Everyone has said what can be said but this is just to complement with regards to what you call mutual exclusion. You are asking if there won't be such a problem. A thread-safe program must ensure that that if threadA is using say a block of code block1 no other thread will access it until the thread is done. So, if I understand well what you mean by mutual exclusion, yes threads accessing the same synchronized (thread-safe) shared resource are mutually exclusive because they both can't access it at the same time.
Java practically does much of the hard for you if you choose one of the proposed safe Map implementation. Now if your Hashtable ( or whatever else thread-safe mao you prefer ) is a shared resource, the only thing you need to take care of is the happens-before relation. It will be important if one thread is reading data and the other writing data.
More can be found at java concurrency tutorial and java concurrent package docs

Why `synchronized` was made illegal for variables?

It is a very easy question but I cant get the idea behind it:
Why synchronized cannot be assigned to Java variables?
It can be assigned to methods and blocks, only.
I personally think this would be a very neat addition to the Java programming language.
A synchronized block protects the complete code block. A synchronized on a method protects the complete code of the method. In both cases synchronized refers to an object it uses as the monitor - either this (or the current class object) or the specified object.
First: The requirement for a monitor object means that a synchronized field could not be a primitive type.
Second: What should a synchronized on a field do?
There are two possible answers:
protect access to the reference itself XOR
protect access to the object behind the reference.
Option one would be a hen-egg problem: In order to protect the access the field must be first accessed. Try to do this atomically on a multiprocessor might be fun. Furthermore: If the access is a write (i.e. the object changes) then the monitor would be on the first object while the second one is installed ... madness is on this road.
Option two: See this piece of code:
public class Foo {
public synchronized StringBuilder sb = ...;
public void doSomething1(){
StringBuilder sb = this.sb;
sb.append("foo");
}
public void doSomething2(){
this.sb.append("foo");
}
}
Since only the access would be protected, both methods do the same. The first version just makes it a little clearer, that the append call itself is not protected.
Oh, I forgot: In both cases you could use only the mutual exclusion of synchronized - the wait or notify stuff would be unavailable - because you cannot attach any piece of code to the variable.
What is left:
Perhaps just a shortcut for AtomicReference?
This is such a rare usecase, that changing the language itself is not a good option.
they have the volatile keyword for that.
Wouldn't help you. You use synchronized to make a block of code atomic. So most of the time, you have more than one line of code you want to synchronize.
If you're looking for fields that act atomically, try the java.util.concurrent.atomic classes. For instance, an AtomicInteger lets you add numbers to it atomically. If object allocation is a concern and you're sure you need it, AtomicIntegerFieldUpdater<T> (and its ilk) can give you atomic-like access to volatile fields -- but you have to be careful with that, because it's easy to break your code with that approach.

Does a synchronized block prevent other thread access to object?

If I do something to a list inside a synchronized block, does it prevent other threads from accessing that list elsewhere?
List<String> myList = new ArrayList<String>();
synchronized {
mylist.add("Hello");
}
Does this prevent other threads from iterating over myList and removing/adding values?
I'm looking to add/remove values from a list, but at the same time protect it from other threads/methods from iterating over it (as the values in the list might be invalidated)
No, it does not.
The synchronized block only prevents other threads from entering the block (more accurately, it prevents other threads from entering all blocks synchronized on the same object instance - in this case blocks synchronized on this).
You need to use the instance you want to protect in the synchronized block:
synchronized(myList) {
mylist.add("Hello");
}
The whole area is quite well explained in the Java tutorial:
http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Yes, but only if all other accesses to myList are protected by synchronized blocks on the same object. The code sample you posted is missing an object on which you synchronize (i.e., the object whose mutex lock you acquire). If you synchronize on different objects or fail to synchronize at all in one instance, then other threads may very well access the list concurrently. Therefore, you must ensure that all threads have to enter a synchronized block on the same object (e.g., using synchronized (myList) { ... } consistently) before accessing the list. In fact, there is already a factory method that will wrap each method of your list with synchronized methods for you: Collections.synchronizedList.
However, you can certainly use Collections.synchronizedList to wrap your list so that all of its methods are individually synchronized, but that doesn't necessarily mean that your application's invariants are maintained. Individually marking each method of the list as synchronized will ensure that the list's internal state remains consistent, but your application may wish for more, in which case you will need to write some more complex synchronization logic or see if you can take advantage of the Concurrency API (highly recommended).
here the sychronized makes sure that only one thread is adding Hello to the myList at a time...
to be more specific about synchronizing wrt objects yu can use
synchronized( myList ) //object name
{
//other code
}
vinod
From my limited understanding of concurrency control in Java I would say that it is unlikely that the code above would present the behaviour you are looking for.
The synchronised block would use the lock of whatever object you are calling said code in, which would in no way stop any other code from accessing that list unless said other code was also synchronised using the same lock object.
I have no idea if this would work, or if its in any way advised, but I think that:
List myList = new ArrayList();
synchronized(myList) {
mylist.add("Hello");
}
would give the behaviour you describe, by synchronizing on the lock object of the list itself.
However, the Java documentation recommends this way to get a synchronized list:
List list = Collections.synchronizedList(new ArrayList(...));
See: http://download.oracle.com/javase/1.4.2/docs/api/java/util/ArrayList.html

Java Thread - Synchronization issue

From Sun's tutorial:
Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods. (An important exception: final fields, which cannot be modified after the object is constructed, can be safely read through non-synchronized methods, once the object is constructed) This strategy is effective, but can present problems with liveness, as we'll see later in this lesson.
Q1. Is the above statements mean that if an object of a class is going to be shared among multiple threads, then all instance methods of that class (except getters of final fields) should be made synchronized, since instance methods process instance variables?
In order to understand concurrency in Java, I recommend the invaluable Java Concurrency in Practice.
In response to your specific question, although synchronizing all methods is a quick-and-dirty way to accomplish thread safety, it does not scale well at all. Consider the much maligned Vector class. Every method is synchronized, and it works terribly, because iteration is still not thread safe.
No. It means that synchronized methods are a way to achieve thread safety, but they're not the only way and, by themselves, they don't guarantee complete safety in all situations.
Not necessarily. You can synchronize (e.g. place a lock on dedicated object) part of the method where you access object's variables, for example. In other cases, you may delegate job to some inner object(s) which already handles synchronization issues.
There are lots of choices, it all depends on the algorithm you're implementing. Although, 'synchronized' keywords is usually the simplest one.
edit
There is no comprehensive tutorial on that, each situation is unique. Learning it is like learning a foreign language: never ends :)
But there are certainly helpful resources. In particular, there is a series of interesting articles on Heinz Kabutz's website.
http://www.javaspecialists.eu/archive/Issue152.html
(see the full list on the page)
If other people have any links I'd be interested to see also. I find the whole topic to be quite confusing (and, probably, most difficult part of core java), especially since new concurrency mechanisms were introduced in java 5.
Have fun!
In the most general form yes.
Immutable objects need not be synchronized.
Also, you can use individual monitors/locks for the mutable instance variables (or groups there of) which will help with liveliness. As well as only synchronize the portions where data is changed, rather than the entire method.
synchronized methodName vs synchronized( object )
That's correct, and is one alternative. I think it would be more efficient to synchronize access to that object only instead synchronize all it's methods.
While the difference may be subtle, it would be useful if you use that same object in a single thread
ie ( using synchronized keyword on the method )
class SomeClass {
private int clickCount = 0;
public synchronized void click(){
clickCount++;
}
}
When a class is defined like this, only one thread at a time may invoke the click method.
What happens if this method is invoked too frequently in a single threaded app? You'll spend some extra time checking if that thread can get the object lock when it is not needed.
class Main {
public static void main( String [] args ) {
SomeClass someObject = new SomeClass();
for( int i = 0 ; i < Integer.MAX_VALUE ; i++ ) {
someObject.click();
}
}
}
In this case, the check to see if the thread can lock the object will be invoked unnecessarily Integer.MAX_VALUE ( 2 147 483 647 ) times.
So removing the synchronized keyword in this situation will run much faster.
So, how would you do that in a multithread application?
You just synchronize the object:
synchronized ( someObject ) {
someObject.click();
}
Vector vs ArrayList
As an additional note, this usage ( syncrhonized methodName vs. syncrhonized( object ) ) is, by the way, one of the reasons why java.util.Vector is now replaced by java.util.ArrayList. Many of the Vector methods are synchronized.
Most of the times a list is used in a single threaded app or piece of code ( ie code inside jsp/servlets is executed in a single thread ), and the extra synchronization of Vector doesn't help to performance.
Same goes for Hashtable being replaced by HashMap
In fact getters a should be synchronized too or fields are to be made volatile. That is because when you get some value, you're probably interested in a most recent version of the value. You see, synchronized block semantics provides not only atomicity of execution (e.g. it guarantees that only one thread executes this block at one time), but also a visibility. It means that when thread enters synchronized block it invalidates its local cache and when it goes out it dumps any variables that have been modified back to main memory. volatile variables has the same visibility semantics.
No. Even getters have to be synchronized, except when they access only final fields. The reason is, that, for example, when accessing a long value, there is a tiny change that another thread currently writes it, and you read it while just the first 4 bytes have been written while the other 4 bytes remain the old value.
Yes, that's correct. All methods that modify data or access data that may be modified by a different thread need to be synchronized on the same monitor.
The easy way is to mark the methods as synchronized. If these are long-running methods, you may want to only synchronize that parts that the the reading/writing. In this case you would definie the monitor, along with wait() and notify().
The simple answer is yes.
If an object of the class is going to be shared by multiple threads, you need to syncronize the getters and setters to prevent data inconsistency.
If all the threads would have seperate copy of object, then there is no need to syncronize the methods. If your instance methods are more than mere set and get, you must analyze the threat of threads waiting for a long running getter/setter to finish.
You could use synchronized methods, synchronized blocks, concurrency tools such as Semaphore or if you really want to get down and dirty you could use Atomic References. Other options include declaring member variables as volatile and using classes like AtomicInteger instead of Integer.
It all depends on the situation, but there are a wide range of concurrency tools available - these are just some of them.
Synchronization can result in hold-wait deadlock where two threads each have the lock of an object, and are trying to acquire the lock of the other thread's object.
Synchronization must also be global for a class, and an easy mistake to make is to forget to synchronize a method. When a thread holds the lock for an object, other threads can still access non synchronized methods of that object.

Categories