Should synchronized accessed methods be synchronized? - java

I want to access a method from within an synchronized block. Here is an example:
public void doSomething() {
// simple stuff
// a block to reduce the synchronized code to
// what really needs to be synchronized.
synchronized(this) {
if (precondition) {
doSequentialStuff();
}
}
}
private void doSequentialStuff() {
// do stuff needs to be performed sequentially.
}
To write clean code I wondered whether it would be good to make the method doSequentialStuff explicitly synchronized. IMHO this would make no difference in semantic since the lock is in both cases this and the method is guaranteed to be accessed only from the synchronized block. I hope to increase the readability.
Any advice?
Edit:
I modified the example to incorporate the comments.

If there is no legitimate code path by which doHeavyStuff may be executed without holding the lock, then by all means make it synchronized in order to preempt any future bugs introduced by an unwary developer. The readability of code can only improve what way.

It's probably better to go with an assert to check that the lock is being held. Note, you do need assertions enabled for the check to be performed.
assert Thread.holdsLock(this);
Generally if you are using this sort of private method it tends to indicate that you should split the class into two. An outer layer does the locking and perhaps other things appropriate for the client, whereas a deeper layer is more concerned with implementation.
Use of this to lock is dubious. Generally it's better to use a private explicit lock object.

Have a look at http://weblogs.java.net/blog/mason/archive/2006/09/rechecking_doub.html, it has got similar pattern covered (uses singleton as an example, but you can easily retrofit it for your case).

Related

Are Mutable Atomic References a Bad Idea?

I have a data structure that I occasionally wish to modify, and occasionally wish to replace outright. At the moment, I'm storing this in an AtomicReference, and using synchrnonized blocks (synchronized on the AtomicReference itself, not its stored value) when I need to modify it, rather than replace it.
So something like:
public void foo(AtomicReference reference){
synchronized(reference){
reference.get()
.performSomeModification();
}
}
Notice that the modifying call is a member of the wrapped value, not the atomic reference, and is not guaranteed to have any thread safety of its own.
Is this safe? Findbugs (a freeware code reviewing tool) had this to say about it, so now I'm worried there's something happening under the hood, where it may be prematurely releasing the lock or something. I've also seen documentation referencing AtomicReference as specifically for immutable things.
Is this safe? If it isn't I could create my own Reference-storing class that I would be more certain about the behavior of, but I don't want to jump to conclusions.
From the linked documentation:
For example, synchronizing on an AtomicBoolean will not prevent other threads from modifying the AtomicBoolean.
It can't prevent other threads from modifying the AtomicBoolean because it can't force other threads to synchronize on the AtomicBoolean.
If I understand your question correctly, your intention is to synchronize calls to performSomeModification(). The code you've written will achieve that, if and only if every call to performSomeModification() is synchronized on the same object. As in the example from the docs, the basic problem is the enforceability of that requirement. You can't force other callers to synchronize on the AtomicReference. You or some other developer who comes after you could easily call performSomeModification() without external synchronization.
You should make it hard to use your API incorrectly. Since AtomicReference is a generic type (AtomicReference<V>), you can enforce the synchronization in a variety of ways, depending on what V is:
If V is an interface, you could easily wrap the instance in a synchronized wrapper.
If V is a class that you can modify, you could synchronize performSomeModification(), or create a subclass in which it is synchronized. (Possibly an anonymous subclass produced by a factory method.)
If V is a class that you cannot modify, it may be difficult to wrap. In that case, you could encapsulate the AtomicReference in a class that you do control, and have that class perform the required synchronization.
Are Mutable Atomic References a Bad Idea?
Definitely not! AtomicReference is designed to provide thread-safe, atomic updates of the underlying reference. In fact, the Javadoc description of AtomicReference is:
An object reference that may be updated atomically.
So they most definitely are designed to be mutated!
Is this safe?
It depends on what you mean by "safe", and what the rest of your code is doing. There's nothing inherently unsafe about your snippet of code in isolation. It's perfectly valid, though perhaps a bit unusual, to synchronize on an AtomicReference. As a developer unfamiliar with this code, I would see the synchronization on reference and assume that it means that the underlying object may be replaced at any time, and you want to make sure your code is always operating on the "newest" reference.
The standard best practices for synchronization apply, and violating them could result in unsafe behavior. For example, since you say performSomeModification() is not thread-safe, it would be unsafe if you accessed the underlying object somewhere else without synchronizing on reference.
public void bar(AtomicReference reference) {
// no synchronization: performSomeModification could be called on the object
// at the same time another thread is executing foo()
reference.get().performSomeModification();
}
If could also be "unsafe" if your application requires that only one instance of the underlying object be operated on at any one time, and you haven't synchronized on the reference when .set()ing it:
public void makeNewFoo(AtomicReference reference) {
// no synchronication on "reference", so it may be updated by another thread
// while foo() is executing performSomeModification() on the "old" reference
SomeObject foo = new SomeObject();
reference.set(foo);
}
If you need to synchronize on the AtomicReference, do so, it's perfectly safe. But I would highly recommend adding a few code comments about why you're doing it.

Can synchronized methods serve all purposes which a synchronized block can?

Suppose i have a code snippet where i want to insert a node in a Linked List and for consistency i used following coding mechanism : Assume that current and next are elements of LinkedList where current represent the Object we are working on and next represent the next object of List.
synchronized(current) {
synchronized(next) {
.............
}
}
and i performed an insertafter for current Object. Can the same functionality be achieved through synchronized methods. Since we can obtain lock only on a single object. So synchronized insertAfter wont prevent someone to use insertBefore.
A synchronized method is nothing but syntactic sugar for synchronized(this) {...}.
So the literal answer to your question is "not easily". You would need two different objects where the two synchronized methods are declared, and call one from the other. But it seems like a bad idea.
In general, I question the goal of trying to reduce an explicit synchronized block to a synchronized method. Synchronized blocks are more readable, and let you encapsulate the lock object to prevent undesired lock contention if some other code decides to use the same instance as the lock for some reason.
Also, are you sure you need the kind of fine-grained locking you're trying to do? This seems error-prone... a more straightforward code would synchronize on the same object for any operation on the list.
This pattern is well know to result in what is called deadly embrace. Imagine someone else making use of your code and also doing the equivalent of an insertBefore:
synchronized(next) {
synchronized(current) {
.............
}
}
This would obviously end in tears.
The obvious answer is not to synchronize on the nodes but on the joins between the nodes.

speed of nested synchronized

Is a nested synchronized block faster to get into than a normal synchronized block? Or for example, which of the following routines is faster:
void routine1(SyncClass a) {
a.syncMethod1();
a.syncmethod2();
a.syncMethod1();
}
void routine2(SyncClass a) {
synchronized(a) {
a.syncMethod1();
a.syncmethod2();
a.syncMethod1();
}
}
The methods are synchronized. I am considering the use of a thread safe object in a situation where thread safety is not needed. So level of concurrency is not affected.
Also, is the answer platform dependant?
You're better off synchronizeding the smallest code elements you can, performance-wise, regardless of the platform.
Wrapping a number of synchronized calls in a synchronized block will reduce concurrency (and so, performance). Only do it if you need that particular sequence of calls to be synchronized.
If you're concerned about the performance impact besides that which is derived from concurrency, I don't know which is faster. However, I would expect that difference in performance in both of the methods you describe is imperceptible.
It appears that the answer is yes, as per comments left on the question. But with two caveats.
1) Due to fewer opportunities for parallel execution, threads may wait on each other more often.
2) The compiler may optimize this way automatically.

Is there a way to ensure some statements are executed in atomic way

Having some line of statements, is there a simple way to assure it is executed in atomic way?
Atomic? No. Despite what people are saying here, thread-safe doesn't mean atomic:
// this is NOT atomic!
synchronized(this) {
makeChangeA();
makeChangeB();
}
if makeChangeB() throws an exception, makeChangeA() will not rollback it's change.
Definition of atomic is "executed either completely, or not at all". Synchronized block is not atomic.
If your emphasis is on "simple way", you can try out the #Synchronized annotation of Project Lombok.
synchronized (obj)
{
//any other thread synchronizing against obj waits until this block is done
}
Edit:
As road to yamburg mentioned, this is not atomicity; I had assumed you simply wanted to ensure that two blocks do not overlap in execution. If in fact you are looking for an atomic action, then you need to employ the user of transactions, which are by no means easy. See Atomicity and Transaction Processing for more info.
Furthermore, if you're guaranteeing atomicity, chances are you're also looking for consistency, isolation, and durability, collectively known as the ACID properties. These are also explained on the second page in detail.
As mentioned by others, synchronized does not provide true atomicity. However, it depends on what you want to achieve? If you’re interested in mutual exclusion only, than a synchronized block may help you very well.
Some atomic operations, however, are possible. Have a look at the package java.util.concurrent.atomic, which, for example, provides atomicIntegers which may be incremented atomically and retrieved in one step.
Otherwise you’ll need to implement your own solution, like with Semaphors which halt all other threads. But note, that even if you achieve to to block all other threads of your process their might as well other processes which interfere with what you are doing (I’m speaking of other OS processes, not only those running at the JVM).
But truly, what do you want to achieve? I’m pretty sure most daily use cases can be be tackled with synchronized blocks / methods and/or the mentioned atomic-pacakge.
put them in a synchronized block, then it is atomic for the JVM.
public class MyClass {
//the English word is synchronizer, not syncronisator
private static final Object syncronisator = new Object();
public void doSomething() {
doSomethingNotSyncronized();
synchronized(syncronisator) {
doItAtomic1():
doItAtomic2():
}
doSomethingNotSyncronized2();
}
}
BTW: if you want to synchronize the complete method with the instance of MyClass, then you could use:
public class MyClass {
public void synchronized doSomething() {
doItAtomic1():
doItAtomic2():
}
}
Edit:
Road to yamburg is right, atomic is not only synchronization, but mean also everything or none.

Collection.synchronizedMap vs synchronizing individual methods in HashMap

What is the difference between a Collections.synchronizedMap() and a wrapper around a HashMap with all the methods synchronized. I dont see any difference becuase Collections.synchronizedMap() internally maintains the same lock for all methods.
Basically, what is the difference between the following code snippets
Class C {
Object o;
public void foo() {
synchronized(o) {
// thread safe code here
}
}
}
and
Class C {
Object o;
public synchronized void foo() {
}
}
There is only one difference:
Collections.synchronizedMap is able to use a different monitor than itself.
Using synchronized methods is the same as using sychnchonized(this)-blocks, which means, the wrapper would be the monitor and could be locked from the outside of the wrapper.
If you doesn't want an outside application to lock your monitor, you need to hide it.
On the other side, if you want to call multiple methods in a thread safe fashion, it is the easiest way to lock the whole collection (but it's not very scaleable, indeed).
Ps: For reuse, it's better to delegate the method calls to a backup-Map than to override the class, because you can switch to another Map implementation later, without changing your wrapper.
Both approaches acquire a monitor on the object and so should perform exactly the same. The main reason for the difference is architectural. The synchronized wrapper allows extending the basic non-thread safe variation easily.
Having said that don't use either, use ConcurrentHashMap. It uses lock striping so it's much quicker to use than either approach (as they are the same in terms of overhead + contention). Lock striping allows segments of the backing array to be locked independently. This means it's less probable that two threads will request to acquire the same lock.
Do not reinvent the wheel and use what is provided by the API.
You should always decorate rather than lumping everything and all feartures into one big featured class.
Always take the plain Map and decorate it with Collections or use a java.util.concurrent and use a real lock, so one can atomically inspect and update the map. Tomorrow you might want to change the Hashtable to a Treemap and you will be in trouble if your stuck with a hashtable.
So, why do you ask? :) Do you really believe that if class is placed in java.util package then some magic happens and its java code works in some tricky way?
It really just wraps all methods with synchronized {} block and nothing more.
UPD: the difference is that you have much less chances to make a mistake if you use synchronized collection instead of doing all synchronization stuff by yourself.
UPD 2: as you can see in sources they use 'mutex'-object as monitor. When you use synchronized modifier in method signature (i.e. synchronized void doSmth()) current instance of your object (i.e. this) is used as a monitor. Two blocks of code below are the same:
1.
synchronized public void doSmth () {
someLogic ();
moreLogic ();
}
synchronized public static void doSmthStatic () {
someStaticLogic ();
moreStaticLogic ();
}
2.
public void doSmth () {
synchronized (this) {
someLogic ();
moreLogic ();
}
}
public static void doSmthStatic () {
synchronized (ClassName.class) {
someStaticLogic ();
moreStaticLogic ();
}
}
If thread safety is the case, use concurrency package data structures. Using the wrapper class will reduce all accesses to the Map into a sequential queue.
a) Threads waiting to do operations at totally different points in the Map will be waiting for the same lock. Based on the number of threads this can affect the application performance.
b) Consider compound operations on the Map. Using a wrapper with a Single lock will not help. For example. "Look if present then add" kind of operations. Thread syncronization will again become an issue.

Categories

Resources