I have a crash in the following code:
private LocalBundle(Bundle b, Map<Bundle, LocalBundle> clonnedObjs) {
this();
synchronized (b.getVariables()) { // b.getVariables() is Set
addFrom(b, clonnedObjs);
}
}
but in addFrom I get the crash:
private synchronized void addFrom(Bundle b, Map<Bundle, LocalBundle> clonnedObjs) {
Set<TaintedVariable> variablesOfBundle = b.getVariables();
for(TaintedVariable v : variablesOfBundle) {
Exception message:
Exception in thread "pool-4-thread-1" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at x.y.z.LocalBundle.addFrom(VisitedNodesWithBundle.java:198)
Does someone know why it happens? I wrapped with synchronized (b.getVariables()), but it looks like that two threads are executing for(TaintedVariable v : variablesOfBundle)
The thing to remember about synchronized is that it only guarantees exclusive access if everybody accessing the shared resource also synchronizes.
For example, you can synchronize access to a shared variable:
synchronized (foo) {
foo.setBar();
}
And you can think that you have exclusive access to it. However, there is nothing to stop another thread just doing something without the synchronized block:
foo.setBar(); // No synchronization first.
From your description, it sounds like this is happening; you've not given any details of what the "rogue" thread is doing, though.
If it is simply adding elements to the set, you can make your set synchronized when you create it:
Collections.synchronizedSet(new HashSet<TaintedVariable>());
Now individual calls to methods on the set will be synchronized, and so you would no longer get a CME. Note, however, that the synchronization is applied per method call: if you make a sequence of calls (e.g. if set contains foo then add bar), you need an explicit synchronized block around that logic.
I'm not sure, that the reason is another thread. Take a closer look at javadoc for this exception. It's said that:
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
That means, that you may cause such exception in a single thread if you try to modify the collection while you are iterating over it.
You have to check out, whether your code tries to modify the variablesOfBundle collection in this for-loop
for(TaintedVariable v : variablesOfBundle)
Related
I have a situation and I need some advice about synchronized block in Java. I have a Class Test below:
Class Test{
private A a;
public void doSomething1(String input){
synchronized (a) {
result = a.process(input);
}
}
public void doSomething2(String input){
synchronized (a) {
result = a.process(input);
}
}
public void doSomething3(String input){
result = a.process(input);
}
}
What I want is when multi threads call methods doSomeThing1() or doSomeThing2(), object "a" will be used and shared among multi threads (it have to be) and it only processes one input at a time (waiting until others thread set object "a" free) and when doSomeThing3 is called, the input is processed immediately.
My question is will the method doSomeThing3() be impacted my method doSomeThing1() and doSomeThing2()? Will it have to wait if doSomeThing1() and doSomeThing2() are using object "a"?
A method is never impacted by anything that your threads do. What gets impacted is data, and the answer to your question depends entirely on what data are updated (if any) inside the a.process() call.
You asked "Variable reference or memory is blocked?"
First of all, "variable" and "memory" are the same thing. Variables, and fields and objects are all higher level abstractions that are built on top of the lower-level idea of "memory".
Second of all, No. Locking an object does not prevent other threads from accessing or modifying the object or, from accessing or modifying anything else.
Locking an object does two things: It prevents other threads from locking the same object at the same time, and it makes certain guarantees about the visibility of memory updates. The simple explanation is, if thread X updates some variables and then releases a lock, thread Y will be guaranteed to see the updates only after it has acquired the same lock.
What that means for your example is, if thread X calls doSomething1() and modifies the object a; and then thread Y later calls doSomething3(), thread Y is not guaranteed to see the the updates. It might see the a object in its original state, it might see it in the fully updated state, or it might see it in some invalid half-way state. The reason why is because, even though thread X locked the object, modified it, and then released the lock; thread Y never locked the same object.
In your code, doSomething3() can proceed in parallel with doSomething1() or doSomething2(), so in that sense it does what you want. However, depending on exactly what a.process() does, this may cause a race condition and corrupt data. Note that even if doSomething3() is called, any calls to doSomething1() or doSomething2() that have started will continue; they won't be put in abeyance while doSomething3() is processed.
I know that in a program that works with multiple threads it's necessary to synchronize the methods because it's possible to have problems like race conditions.
But I cannot understand why we need to synchronize also the methods that need just to read a shared variable.
Look at this example:
public ConcurrentIntegerArray(final int size) {
arr = new int[size];
}
public void set(final int index, final int value) {
lock.lock();
try {
arr[index] = value;
} finally {
lock.unlock();
}
}
public int get(final int index) {
lock.lock();
try {
return arr[index];
} finally {
lock.unlock();
}
}
They did a look on the get and also on the set method. On the set method I understand why. For example if I want to put with Thread1 in index=3 the number 5 and after some milliseconds the Thread2 have to put in index=3 the number 6. Can it happen that I have in index=3 in my array still a 5 instead of a 6 (if I don't do a synchronization on the method set)? This because the Thread1 can have a switch-context and so the Thread2 enter in the same method put the value and after the Thread1 assign the value 5 on the same position So instead of a 6 I have a 5.
But I don't understand why we need (look the example) to synchronize also the method get. I'm asking this question because we need just to read on the memory and not to write.So why we need also on the method get to have a synchronization? Can someone give to me a very simple example?
Both methods need to be synchronized. Without synchronization on the get method, this sequence is possible:
get is called, but the old value isn't returned yet.
Another thread calls set and updates the value.
The first thread that called get now examines the now-returned value and sees what is now an outdated value.
Synchronization would disallow this scenario by guaranteeing that another thread can't just call set and invalidate the get value before it even returns. It would force a thread that calls set to wait for the thread that calls get to finish.
If you do not lock in the get method than a thread might keep a local copy of the array and never refreshes from the main memory. So its possible that a get never sees a value which was updated by a set method. Lock will force the visibility.
Each thread maintain their own copy of value. The synchronized ensures that the coherency is maintained between different threads. Without synchronized, one can never be sure if any one has modified it. Alternatively, one can define the variable as volatile and it will have the same memory effects as synchronized.
The locking action also guarantees memory visibility. From the Lock doc:
All Lock implementations must enforce the same memory synchronization semantics as provided by the built-in monitor lock, [...]:
A successful lock operation has the same memory synchronization effects as a successful Lock action.
A successful unlock operation has the same memory synchronization effects as a successful Unlock action.
Without acquiring the lock, due to memory consistency errors, there's no reason a call to get needs to see the most updated value. Modern processors are very fast, access to DRAM is comparatively very slow, so processors store values they are working on in a local cache. In concurrent programming this means one thread might write to a variable in memory but a subsequent read from a different thread gets a stale value because it is read from the cache.
The locking guarantees that the value is actually read from memory and not from the cache.
Please, help me understand the error I am getting:
private void replayHistory() {
synchronized (alarmsHistory) {
for (AlarmEvent alarmEvent : alarmsHistory) {
LOG.error("replayHistory " + alarmEvent.type + " " + alarmEvent.source);
sendNotification(alarmEvent.type, alarmEvent.source, alarmEvent.description,
alarmEvent.clearOnOtherStations, alarmEvent.forceClearOnOtherStations);
}
}
}
and the method that adds an element to it
private void addToAlarmsHistory(AlarmEvent alarmEvent) {
synchronized (alarmsHistory) {
LOG.error("addToAlarmsHistory " + alarmEvent.type + " " + alarmEvent.source);
alarmsHistory.add(alarmEvent);
}
}
both methods and the Set
private volatile Set<AlarmEvent> alarmsHistory = new LinkedHashSet<AlarmEvent>();
are defined in
JmxGwReloadThread extends Thread class
which is an inner class in
AlarmManager class
that has a method
private void addToReplayHistory(AlarmEvent alarmEvent) {
if ((jmxThread != null) && (jmxThread.isAlive())) {
jmxThread.addToAlarmsHistory(alarmEvent);
}
}
which is being called by different interfaces (cannot assure when and how often)
At some point JmxThread is started and calls replayHistory method
java.util.ConcurrentModificationException is thrown, the root is from the
for (AlarmEvent alarmEvent : alarmsHistory) {
The code propably tries to add an element to the alarmsHistory and when interator
java.util.ConcurrentModificationException
at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:390)
at java.util.LinkedHashMap$KeyIterator.next(LinkedHashMap.java:401)
at AlarmManager$JmxGwReloadThread.replayHistory(AlarmManager.java:568)
at AlarmManager$JmxGwReloadThread.run(AlarmManager.java:532)
throws exception upon calling nextEntry, but should't synchronization prevent from such an issue?
Logs show that synchronization does not work - replayHistory should iterate over all its elements (I can asure its more then one single HEARTBEAT_INFO FM) but it's interrupted by the addToReplayHistory call.
2013-07-11 11:58:33,951 Thread-280 ERROR AlarmManager$JmxGwReloadThread.replayHistory(AlarmManager.java:570) - replayHistory HEARTBEAT_INFO FM
2013-07-11 11:58:33,951 Thread-280 ERROR AlarmManager$JmxGwReloadThread.addToAlarmsHistory(AlarmManager.java:550) - addToAlarmsHistory HEARTBEAT_INFO FM
2013-07-11 11:58:33,952 Thread-280 ERROR Log4jConfigurator$UncaughtExceptionHandler.uncaughtException(Log4jConfigurator.java:253) - Detected uncaught exception in thread: Thread-280
One thing OP (and probably most people) should be aware of:
ConcurrentModificationException has nothing to do with multi-threading.
Although multi-threading makes it much easier to happen, but the core of this problem has nothing to do with multi-threading.
This is mostly caused by scenario like,
Get the iterator from a collection,
Before finish using that iterator, the collection is structurally modified.
Keep on using the iterator after 2. The iterator will detect the collection is structurally modified and will throw out ConcurrentModificationException.
Of course, not all collection have such behavior, e.g. ConcurrentHashMap. Definition of "Structurally Modified" is different for different collection too.
That means, even I have only 1 thread, if I do something like:
List<String> strings = new ArrayList<String>();
//....
for (String s: strings) { // iterating through the collection
strings.add("x"); // structurally modifying the collection
}
I will get ConcurrentModificationException even it is all happening in single thread.
There are different ways to solve the problem, depending on your requirement or problem. e.g.
If it is simply due to multi-thread access, proper synchronize access can be one solution
You may make use of Collection that iterator is safe from structural modification (e.g. ConcurrentHashMap)
Adjust your logic to either re-acquire the iterator again if you modified the collection, or makes your modification using the iterator (some collection impls allows that), or make sure modification to collection happens after you finish using the iterator.
Given that your code seems having proper synchronization on alarmHistory, there are two directions you would want to check
Is there any possible modification of alarmHistory inside sendNotification()? For example, adding or removing from alarmHistory?
Is there other possible unsynchronized access to alarmHistory which may modify the structure?
If one thread iterates, and another thread adds, you're hosed.
Given that your code seems to synchronise access to the two relevant blocks of code, look for other unsynchronized code that adds/removes from alarmsHistory.
The only idea which comes to my head that you have an intricate logic behind the scene. I think the sendNotification somehow recursively invokes addToReplayHistory. So, the multithreading is a red herring, the log file shows only one thread involved, and immideately after sendNotification there is addToReplayHistory call which modifies the collection and breaks the interator.
More info is in the javadoc for the exception:
Note that this exception does not always indicate that an object has
been concurrently modified by a different thread. If a single thread
issues a sequence of method invocations that violates the contract of
an object, the object may throw this exception. For example, if a
thread modifies a collection directly while it is iterating over the
collection with a fail-fast iterator, the iterator will throw this
exception.
To add some details to kan's answer:
The synchronized block in Java is reentrant:
Reentrant SynchronizationRecall that a thread cannot acquire a lock owned by another thread. But a thread can acquire a lock that it already owns. Allowing a thread to acquire the same lock more than once enables reentrant synchronization. This describes a situation where synchronized code, directly or indirectly, invokes a method that also contains synchronized code, and both sets of code use the same lock. Without reentrant synchronization, synchronized code would have to take many additional precautions to avoid having a thread cause itself to block.
So like kan pointed out, it might in fact be that not multiple threads are modifying your collection but only one thread which, due to the reentrant behavior, may always acquire the lock.
The things you should look for to fix the exception are recursive calls between synchronized blocks, or unsychronized access to alarmsHistory.
You can also look into concurrent collections like ConcurrentSkipList or CopyOnWriteArraySet. Both should prevent the exception, but beware of their behavior and performance characteristics described in the JavaDoc.
I known a Hashtable is synchronized, but why its get() method is synchronized?
Is it only a read method?
If the read was not synchronized, then the Hashtable could be modified during the execution of read. New elements could be added, the underlying array could become too small and could be replaced by a bigger one, etc. Without sequential execution, it is difficult to deal with these situations.
However, even if get would not crash when the Hashtable is modified by another thread, there is another important aspect of the synchronized keyword, namely cache synchronization. Let's use a simplified example:
class Flag {
bool value;
bool get() { return value; } // WARNING: not synchronized
synchronized void set(bool value) { this->value = value; }
}
set is synchronized, but get isn't. What happens if two threads A and B simultaneously read and write to this class?
1. A calls read
2. B calls set
3. A calls read
Is it guaranteed at step 3 that A sees the modification of thread B?
No, it isn't, as A could be running on a different core, which uses a separate cache where the old value is still present. Thus, we have to force B to communicate the memory to other core, and force A to fetch the new data.
How can we enforce it? Everytime, a thread enters and leaves a synchronized block, an implicit memory barrier is executed. A memory barrier forces the cache to be updated. However, it is required that both the writer and the reader have to execute the memory barrier. Otherwise, the information is not properly communicated.
In our example, thread B already uses the synchronized method set, so its data modification is communicated at the end of the method. However, A does not see the modified data. The solution is to make get synchronized, so it is forced to get the updated data.
Have a look in Hashtable source code and you can think of lots of race conditions that can cause problem in a unsynchronized get() .
(I am reading JDK6 source code)
For example, a rehash() will create a empty array, and assign it to the instance var table, and put the entries from old table to the new one. Therefore if your get occurs after the empty array assignment, but before actually putting entries in it, you cannot find your key even it is in the table.
Another example is, there is a loop iterate thru the linked list at the table index, if in middle in your iteration, rehash happens. You may also failed to find the entry even it exists in the hashtable.
Hashtable is synchronized meaning the whole class is thread-safe
Inside the Hashtable, not only get() method is synchronized but also many other methods are. And particularly put() method is synchronized like Tom said.
A read method must be synchronized as a write method because it will make sure the visibility and the consistency of the variable.
I am writing a multi-threaded application that mimics a movie theater. Each person involved is its own thread and concurrency must be done completely by semaphores. The only issue I am having is how to basically link threads so that they can communicate (via a pipe for instance).
For instance:
Customer[1] which is a thread, acquires a semaphore that lets it walk up to the Box Office. Now Customer[1] must tell the Box Office Agent that they want to see movie "X". Then BoxOfficeAgent[1] also a thread, must check to make sure the movie isn't full and either sell a ticket or tell Customer[1] to pick another movie.
How do I pass that data back and forth while still maintaining concurrency with the semaphores?
Also, the only class I can use from java.util.concurrent is the Semaphore class.
One easy way to pass data back and forth between threads is to use the implementations of the interface BlockingQueue<E>, located in the package java.util.concurrent.
This interfaces has methods to add elements to the collection with different behaviors:
add(E): adds if possible, otherwise throws exception
boolean offer(E): returns true if the element has been added, false otherwise
boolean offer(E, long, TimeUnit): tries to add the element, waiting the specified amount of time
put(E): blocks the calling thread until the element has been added
It also defines methods for element retrieval with similar behaviors:
take(): blocks until there's an element available
poll(long, TimeUnit): retrieves an element or returns null
The implementations I use most frequently are: ArrayBlockingQueue, LinkedBlockingQueue and SynchronousQueue.
The first one, ArrayBlockingQueue, has a fixed size, defined by a parameter passed to its constructor.
The second, LinkedBlockingQueue, has illimited size. It will always accept any elements, that is, offer will return true immediately, add will never throw an exception.
The third, and to me the most interesting one, SynchronousQueue, is exactly a pipe. You can think of it as a queue with size 0. It will never keep an element: this queue will only accept elements if there's some other thread trying to retrieve elements from it. Conversely, a retrieval operation will only return an element if there's another thread trying to push it.
To fulfill the homework requirement of synchronization done exclusively with semaphores, you could get inspired by the description I gave you about the SynchronousQueue, and write something quite similar:
class Pipe<E> {
private E e;
private final Semaphore read = new Semaphore(0);
private final Semaphore write = new Semaphore(1);
public final void put(final E e) {
write.acquire();
this.e = e;
read.release();
}
public final E take() {
read.acquire();
E e = this.e;
write.release();
return e;
}
}
Notice that this class presents similar behavior to what I described about the SynchronousQueue.
Once the methods put(E) gets called it acquires the write semaphore, which will be left empty, so that another call to the same method would block at its first line. This method then stores a reference to the object being passed, and releases the read semaphore. This release will make it possible for any thread calling the take() method to proceed.
The first step of the take() method is then, naturally, to acquire the read semaphore, in order to disallow any other thread to retrieve the element concurrently. After the element has been retrieved and kept in a local variable (exercise: what would happen if that line, E e = this.e, were removed?), the method releases the write semaphore, so that the method put(E) may be called again by any thread, and returns what has been saved in the local variable.
As an important remark, observe that the reference to the object being passed is kept in a private field, and the methods take() and put(E) are both final. This is of utmost importance, and often missed. If these methods were not final (or worse, the field not private), an inheriting class would be able to alter the behavior of take() and put(E) breaking the contract.
Finally, you could avoid the need to declare a local variable in the take() method by using try {} finally {} as follows:
class Pipe<E> {
// ...
public final E take() {
try {
read.acquire();
return e;
} finally {
write.release();
}
}
}
Here, the point of this example if just to show an use of try/finally that goes unnoticed among inexperienced developers. Obviously, in this case, there's no real gain.
Oh damn, I've mostly finished your homework for you. In retribution -- and for you to test your knowledge about Semaphores --, why don't you implement some of the other methods defined by the BlockingQueue contract? For example, you could implement an offer(E) method and a take(E, long, TimeUnit)!
Good luck.
Think it in terms of shared memory with read/write lock.
Create a buffer to put the message.
The access to the buffer should be controlled by using a lock/semaphore.
Use this buffer for inter thread communication purpose.
Regards
PKV