Do I need extra synchronization when using a BlockingQueue? - java

I have a simple bean #Entity Message.java that has some normal properties. The life-cycle of that object is as follows
Instantiation of Message happens on Thread A, which is then enqueued into a blockingQueue
Another thread from a pool obtains that object and do some stuff with it and changes the state of Message, after that, the object enters again into the blockingQueue. This step is repeated until a condition makes it stop. Each time the object gets read/write is potentially from a different thread, but with the guarantee that only one thread at a time will be reading/writing to it.
Given that circumstances, do I need to synchronize the getters/setters ? Perhaps make the properties volatile ? or can I just leave without synchronization ?
Thanks and hope I could clarify what I am having here.

No, you do not need to synchronize access to the object properties, or even use volatile on the member variables.
All actions performed by a thread before it queues an object on a BlockingQueue "happen-before" the object is dequeued. That means that any changes made by the first thread are visible to the second. This is common behavior for concurrent collections. See the last paragraph of the BlockingQueue class documentation:
Memory consistency effects: As with other concurrent collections, actions in a thread prior to placing an object into a BlockingQueue happen-before actions subsequent to the access or removal of that element from the BlockingQueue in another thread.
As long as the first thread doesn't make any modifications after queueing the object, it will be safe.

You don't need to do synchronization yourself, because the queue does it for you already.
Visibility is also guaranteed.

If you're sure that only one thread at a time will access your object, then you don't need synchronisation.
However, you can ensure that by using the synchronized keyword: each time you want to access this object and be sure that no other thread is using the same instance, wrap you code in a synchronized block:
Message myMessage = // ...
synchronized (myMessage) {
// You're the only one to have access to this instance, do what you want
}
The synchronized block will acquire an implicit lock on the myMessage object. So, no other synchronized block will have access to the same instance until you leave this block.

It would sound like you could leave of the synchronized off the methods. The synchronized simply locks the object to allow only a single thread to access it. You've already handled that with the blocking queue.
Volatile would be good to use, as that would ensure that each thread has the latest version, instead of a thread local cache value.

Related

Why to use wait method on strings or other objects?

I have following piece of code:
synchronized void myMethod() {
String s="aaa";
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
The code throws exception ...
I have seen codes using wait method on threads which is self explainable and logical..
why would one use wait method on an object like string instead of using it on main thread?
what is its use?
are there any practical implementations like this?
Thanks in advance
Your sample code won't work because the method is synchronizing on the instance that myMethod is called on, while the wait is called on the string. It will cause an IllegalMonitorStateException. You have to call wait and notify on the same object that you're locking on. The threads that get notified are the ones waiting on the lock that notify is called on.
Locking on a string object is a bad idea, don't do it. You don't want to lock on things where you can't reason about who can acquire them because anybody could acquire them. Some other code elsewhere in the application could be locking on the same string value, and you'd have the potential for strange interactions, deadlocking because the other code was taking your lock, or have the other code notifying you. Do you want to have to think about how strings are pooled when debugging some multithreading behavior?
You can limit who can acquire your lock by defining your own lock and making it private, like this:
private final Object LOCK = new Object();
so only threads calling the methods of the object you're controlling access to can acquire the lock:
public void myMethod() {
synchronized(LOCK) {
...
}
}
That way you know exactly what can acquire the lock, it's not available to every thread in the application. The lock can be acquired by anything that can get a reference to that object, so keep the reference private.
The way your example uses wait without a loop with a condition variable is very suspect. A thread can exit from a call to wait without having been notified. Even if a thread is notified, that doesn't give it any special priority with the scheduler. Another thread can barge in and do something, possibly something affecting the state that the notification was alerting the waiting thread to, between the time the thread is notified and the time that the thread can reacquire the lock it gave up when it started waiting. For both reasons there needs to be a loop where the thread retests a condition when it wakes from waiting.
Also if by "codes using wait method on threads" you mean code where a Thread object is used as a lock, that's another thing to avoid doing, see the API documentation for Thread#join:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
You first need to be synchronized on the Object before calling wait. This is where you are getting the exception from.
void test() {
String s = "AAA";
synchronized( s ) {
s.wait();
}
}
The same thing must be done when you call notify, but in this case it is a very very bad idea because if a thread enters this method it will never return. Although considering it is a String literal you may be able to get away with it by using the same literal in another method in the same class, but don't count on it.
wait() method is implemented in Object, and String extends object so it can be used.
why someone use it? ask him. its not a programming question.
something i can think of:
he could be using "lock1".wait() in one class and "lock1".notify() in other, it will be something like global lock object
because literals are interned by
the compiler and thus refer to the same object
but its VERY VERY BAD PRACTICE
This is an example of synchronization with no affect.
First of all, it is unlikely you will need to synchronize on String, it is immutable after all, therefore, you don't need it to perform anything asynchronously.
Second, you are likely to be synchronizing on the incorrect object anyways, no correctly written program would use String as a synchronization lock.
Third and finally, s is a local variable. In fact, it holds exactly the same pattern that JCIP specifically tells you not to use if you inline it:
synchronized (new Object()) {
// ...
}
This is synchronization without effect, as it does not guarantee the purpose of the synchronized keyword: serialized access, lock and release semantics that require that only one thread execute the synchronized block at any given time.
Because of this, each thread will have their own lock - not good.

Does it need synchronization if a thread class has just one instance?

Referring to this topic(How to pause Thread execution), Peter Knego said:
Loop must be inside synchronized block.
But I don't see the point of synchronization if only one instance is there.
In another case, if the thread class has multiple instances and they are copping with different variables, does the loop need to be synchronized.
Actually, I wrote a few programs using threads (with multiple instances) without considering synchronization and they works fine.
You must synchronize any access to shared state. If all of your instances access local storage, then they are thread safe. If your methods are thread safe, they do not require synchronization. If you had a static (e.g. global) resource, and modified it in multiple threads then that is likely to be non-thread safe (excluding atomic operations of course).
The answer says
Use synchronized, wait() and notify() for that.
Create an atomic flag (e.g. boolean field) in the thread to be stopped. Stoppable thread monitors this flag in the loop. Loop must be inside synchronized block.
When you need to stop the thread (button click) you set this flag.
Thread sees the flag is set and calls wait() on a common object (possibly itself).
When you want to restart the thread, reset the flag and call commonObject.notify().
You cannot call wait() or notify on an object unless you get a lock on it's monitor. And putting it inside synchronized block is a way to do that.
this is because the wait and notify are part of the condition variable and using them without synchronizing on them leads in the general use-case to race conditions
the normal way of using wait is
synchronized(this){
while(someCondition())
wait();//while loop is needed to combat spurious wakeups
}
and you wake it up with
synchronized(this){
adjustCondition();
notify();
}
if you didn't synchronize on the condition as well then you get into a race for example
you just tested someCondition() and got true so you need to wait. but before you get a chance to another thread executes the adjustCondition();notify(); block
but the first thread will still enter the wait() (because the condition has already been checked) and which may lead to deadlock
The Thread monitor needs to be synchronized in your case. This is done only for the actual wait call, because it requires that. I recommend to have a special wait Object for this to not accidental synchronize on something else.
final static Object threadPauseMonitor = new Object();
// ...
while (shouldPause.get()) {
synchronized(threadPauseMonitor) {
threadPauseMonitor.wait();
}
}
Where shouldPause is an AtomicBoolean. Please note the while to counter the malicious spurious wakeup that can possibly occur.

Some questions on java multithreading,

I have a set of questions regarding Java multithreading issues. Please provide me with as much help as you can.
0) Assume we have 2 banking accounts and we need to transfer money between them in a thread-safe way.
i.e.
accountA.money += transferSum;
accountB.money -= transferSum;
Two requirements exist:
no one should be able to see the intermediate results of the operation (i.e. one acount sum is increased, but others is not yet decreased)
reading access should not be blocked during the operation (i.e. old values of account sums should be shown during the operation goes on)
Can you suggest some ideas on this?
1) Assume 2 threads modify some class field via synchronized method or utilizing an explicit lock. Regardless of synchronization, there are no guarantee that this field will be visible to threads, that read it via NOT synchronized method. - is it correct?
2) How long a thread that is awoken by notify method can wait for a lock? Assume we have a code like this:
synchronized(lock) {
lock.notifyall();
//do some very-very long activity
lock.wait() //or the end of synchronized block
}
Can we state that at least one thread will succeed and grab the lock? Can a signal be lost due to some timeout?
3) A quotation from Java Concurrency Book:
"Single-threaded executors also provide sufficient internal synchronization to guarantee that any memory writes made by tasks are visible to subsequent tasks; this means that objects can be safely confined to the "task thread" even though that thread may be replaced with another from time to time."
Does this mean that the only thread-safety issue that remains for a code being executed in single-threaded executor is data race and we can abandon the volatile variables and overlook all visibility issues? It looks like a universal way to solve a great part of concurrency issues.
4) All standard getters and setters are atomic. They need not to be synchronized if the field is marked as volatile. - is it correct?
5) The initiation of static fields and static blocks is accomplished by one thread and thus need not to be synchronized. - is it correct?
6) Why a thread needs to notify others if it leaves the lock with wait() method, but does not need to do this if it leaves the lock by exiting the synchronized block?
0: You can't.
Assuring an atomic update is easy: you synchronize on whatever object holds the bank accounts. But then you either block all readers (because they synchronize as well), or you can't guarantee what the reader will see.
BUT, in a large-scale system such as a banking system, locking on frequently-accessed objects is a bad idea, as it introduces waits into the system. In the specific case of changing two values, this might not be an issue: it will happen so fast that most accesses will be uncontended.
There are certainly ways to avoid such race conditions. Databases do a pretty good job for ba nk accounts (although ultimately they rely on contended access to the end of a transaction).
1) To the best of my knowledge, there are no guarantees other than those established by synchronized or volatile. If one thread makes a synchronized access and one thread does not, the unsynchronized access does not have a memory barrier. (if I'm wrong, I'm sure that I'll be corrected or at least downvoted)
2) To quote that JavaDoc: "The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object." If you decide to throw a sleep into that synchronized block, you'll be unhappy.
3) I'd have to read that quote several times to be sure, but I believe that "single-threaded executor" is the key phrase. If the executor is running only a single thread, then there is a strict happens-before relationship for all operations on that thread. It does not mean that other threads, running in other executors, can ignore synchronization.
4) No. long and double are not atomic (see the JVM spec). Use an AtomicXXX object if you want unsynchronized access to member variables.
5) No. I couldn't find an exact reference in the JVM spec, but section 2.17.5 implies that multiple threads may initialize classes.
6) Because all threads wait until one thread does a notify. If you're in a synchronized block, and leave it with a wait and no notify, every thread will be waiting for a notification that will never happen.
0) Is a difficult problem because you don't want intermediate results to be visible or to lock readers during the operation. To be honest I'm not sure it's possible at all, in order to ensure no thread sees intermediate results you need to block readers while doing both writes.
If you dont want intermediate results visible then you have to lock both back accounts before doing your writing. The best way to do this is to make sure you get and release the locks in the same order each time (otherwise you get a deadlock). E.G. get the lock on the lower account number first and then the greater.
1) Correct, all access must be via a lock/synchronized or use volatile.
2) Forever
3) Using a Single Threaded Executor means that as long as all access is doen by tasks run by that executor you dont need to worry about thread safety/visibilty.
4) Not sure what you mean by standard getters and setters but writes to most variable types (except double and long) are atomic and so don't need sync, just volatile for visibility. Try using the Atomic variants instead.
5) No, it is possible for two threads to try an init some static code, making naive implementations of Singleton unsafe.
6) Sync and Wait/Notify are two different but related mechanisms. Without wait/notify you'd have to spin lock (i.e. keep getting a lock and polling )on a object to get updates
5) The initiation of static fields and static blocks is accomplished by one thread and thus need not to be synchronized. - is it correct?
VM executes static initialization in a synchronized(clazz) block.
static class Foo {
static {
assert Thread.holdsLock(Foo.class); // true
synchronized(Foo.class){ // redundant, already under the lock
....
0) The only way I can see to do this to to store accountA and accountB in an object stored in an AtomicReference. You then make a copy of the object, modify it, and update the reference if it is still the same as the original reference.
AtomicReference<Accounts> accountRef;
Accounts origRef;
Accounts newRef;
do {
origRef = accountRef.get();
// make a deep copy of origRef
newRef.accountA.money += transferSum;
newRef.accountB.money -= transferSum;
} while(accountRef.compareAndSet(origRef, newRef);

Threadsafe publishing of java object structure?

Assuming that I have the following code:
final Catalog catalog = createCatalog();
for (int i = 0; i< 100; i++{
new Thread(new CatalogWorker(catalog)).start();
}
"Catalog" is an object structure, and the method createCatalog() and the "Catalog" object structure has not been written with concurrency in mind. There are several non-final, non-volatile references within the product catalog, there may even be mutable state (but that's going to have to be handled)
The way I understand the memory model, this code is not thread-safe. Is there any simple way to make it safe ? (The generalized version of this problem is really about single-threaded construction of shared structures that are created before the threads explode into action)
No, there's no simple way to make it safe. Concurrent use of mutable data types is always tricky. In some situations, making each operation on Catalog synchronized (preferably on a privately-held lock) may work, but usually you'll find that a thread actually wants to perform multiple operations without risking any other threads messing around with things.
Just synchronizing every access to variables should be enough to make the Java memory model problem less relevant - you would always see the most recent values, for example - but the bigger problem itself is still significant.
Any immutable state in Catalog should be fine already: there's a "happens-before" between the construction of the Catalog and the new thread being started. From section 17.4.5 of the spec:
A call to start() on a thread
happens-before any actions in the
started thread.
(And the construction finishing happens before the call to start(), so the construction happens before any actions in the started thread.)
You need to synchronize every method that changes the state of Catalog to make it thread-safe.
public synchronized <return type> method(<parameter list>){
...
}
Assuming you handle the "non-final, non-volatile references [and] mutable state" (presumably by not actually mutating anything while these threads are running) then I believe this is thread-safe. From the JSR-133 FAQ:
When one action happens before
another, the first is guaranteed to be
ordered before and visible to the
second. The rules of this ordering are
as follows:
Each action in a thread happens before every action in that thread
that comes later in the program's
order.
An unlock on a monitor happens before every subsequent lock on that
same monitor.
A write to a volatile field happens before every subsequent read
of that same volatile.
A call to start() on a thread happens before any actions in the
started thread.
All actions in a thread happen before any other thread successfully
returns from a join() on that thread.
Since the threads are started after the call to createCatalog, the result of createCatalog should be visible to those threads without any problems. It's only changes to the Catalog objects that occur after start() is called on the thread that would cause trouble.

Why are wait() and notify() declared in Java's Object class?

Why are the wait() and notify() methods declared in the Object class, rather than the Thread class?
Because, you wait on a given Object (or specifically, its monitor) to use this functionality.
I think you may be mistaken on how these methods work. They're not simply at a Thread-granularity level, i.e. it is not a case of just calling wait() and being woken up by the next call to notify(). Rather, you always call wait() on a specific object, and will only be woken by calls to notify on that object.
This is good because otherwise concurrency primitives just wouldn't scale; it would be equivalent to having global namespaces, since any calls to notify() anywhere in your program would have the potential to mess up any concurrent code as they would wake up any threads blocking on a wait() call. Hence the reason that you call them on a specific object; it gives a context for the wait-notify pair to operate on, so when you call myBlockingObject.notify(), on a private object, you can be sure that you'll only wake up threads that called wait methods in your class. Some Spring thread that might be waiting on another object will not be woken up by this call, and vice versa.
Edit: Or to address it from another perspective - I expect from your question you thought you would get a handle to the waiting thread and call notify() on that Thread to wake it up. The reason it's not done this way, is that you would have to do a lot of housekeeping yourself. The thread going to wait would have to publish a reference to itself somewhere that other threads could see it; this would have to be properly synchronized to enforce consistency and visibility. And when you want to wake up a thread you'd have to get hold of this reference, awaken it, and remove it from wherever you read it from. There's a lot more manual scaffolding involved, and a lot more chance of going wrong with it (especially in a concurrent environment) compared to just calling myObj.wait() in the sleeping thread and then myObj.notify() in the waker thread.
The most simple and obvious reason is that any Object (not just a thread)
can be the monitor for a thread. The wait and notify are called on the
monitor. The running thread checks with the monitor. So the wait and notify methods are in Object and not Thread
Because only one thread at a time can own an object's monitor and this monitor is what the threads are waiting on or notifying. If you read the javadoc for Object.notify() and Object.wait() it's described in detail.
The mechanism of synchronization involves a concept - monitor of an object. When wait() is called, the monitor is requested and further execution is suspended until monitor is acquired or InterruptedException occurs. When notify() is called, the monitor is released.
Let's take a scenario if wait() and notify() were placed in Thread class instead of Object class. At one point in the code, currentThread.wait() is called and then an object anObject is accessed.
//.........
currentThread.wait();
anObject.setValue(1);
//.........
When currentThread.wait() is called, monitor of currentThread is requested and no further execution is made until either the monitor is acquired or InterruptedException occurs. Now while in waiting state, if a method foo() of another object anotherObject residing in currentThread is called from another thread, it is stuck even though the called method foo() does not access anObject. If the first wait() method was called on anObject, instead of the thread itself, other method calls (not accessing anObject) on objects residing in the same thread would not get stuck.
Thus calling wait() and notify() methods on Object class(or its subclasses) provides greater concurrency and that's why these methods are in Object class, not in Thread class.
A few of the other answers use the word "monitor", but none explain what it means.
The name "monitor" was coined way back in the 1970s, and it referred to an object that had its own intrinsic lock, and associated wait/notify mechanism. https://en.wikipedia.org/wiki/Monitor_%28synchronization%29
Twenty years later, there was a brief moment in time when desktop, multi-processor computers were new, and it was fashionable to think that the right way to design software for them would be to create object-oriented programs in which every object was a monitor.
Turns out not to have been such a useful idea, but that brief moment happens to be exactly when the Java programming language was invented.
Read here for an explanation of wait and notify.
It would be better to avoid these however in your applications and use the newer java.util.concurrent package.
I will put it in a simple way:
To call wait() or notify() you need to own the object monitor - this means wait() or notify() needs to be present in the synchronized block
synchronized(monitorObj){
monitorObj.wait() or even notify
}
Thats the reason these methods are present in object class
This is because,these methods are for inter thread communication and interthreadcommunication happens by using locks, but locks are associated with objects.hence it is in object class.
Wait and Notify methods are used communication between two Threads in Java. So Object class is correct place to make them available for every object in Java.
Another reason is Locks are made available on per Object basis. Threads needs lock and they wait for lock, they don't know which threads holds lock instead they just know the lock is hold by some thread and they should wait for lock instead of knowing which thread is inside the synchronized block and asking them to release lock

Categories

Resources