Object locking private class members - best practice? (Java) - java

I asked a similar question the other day but wasn't satisfied with the response, mainly because the code I supplied had some issues that people focused on.
Basically, what is the best practice for locking private members in Java? Assuming each private field can only be manipulated in isolation and never together (like in my Test class example below), should you lock each private field directly (example 1), or should you use a general lock object per private field you wish to lock (example 2)?
Example 1: Lock private fields directly
class Test {
private final List<Object> xList = new ArrayList<Object>();
private final List<Object> yList = new ArrayList<Object>();
/* xList methods */
public void addToX(Object o) {
synchronized(xList) {
xList.add(o);
}
}
public void removeFromX(Object o) {
synchronized(xList) {
xList.remove(o);
}
}
/* yList methods */
public void addToY(Object o) {
synchronized(yList) {
yList.add(o);
}
}
public void removeFromY(Object o) {
synchronized(yList) {
yList.remove(o);
}
}
}
Example 2: Use lock objects per private field
class Test {
private final Object xLock = new Object();
private final Object yLock = new Object();
private List<Object> xList = new ArrayList<Object>();
private List<Object> yList = new ArrayList<Object>();
/* xList methods */
public void addToX(Object o) {
synchronized(xLock) {
xList.add(o);
}
}
public void removeFromX(Object o) {
synchronized(xLock) {
xList.remove(o);
}
}
/* yList methods */
public void addToY(Object o) {
synchronized(yLock) {
yList.add(o);
}
}
public void removeFromY(Object o) {
synchronized(yLock) {
yList.remove(o);
}
}
}

Personally I prefer the second form. No other code at all can use that reference (barring reflection, debugging APIs etc). You don't need to worry about whether the internal details of the list tries to synchronize on it. (Any method you call on a list obviously has access to this, so could synchronize on it.) You're purely using it for locking - so you've also got separation of concerns between "I'm a lock" and "I'm a list".
I find that way it's easier to reason about the monitor, as you can easily see all the possible code that uses it.
You may wish to create a separate class purely for use as monitors, with an override for toString() which could help with diagnostics. It would also make the purpose of the variable clearer.
Admittedly this approach does take more memory, and usually you don't need to worry about code locking on this... but I personally feel that the benefit of separating the concerns and not having to worry about whether that code does lock on itself outweighs the efficiency cost. You can always choose to go for the first form if you find that the "wasted" objects are a performance bottleneck for some reason (and after you've analyzed the code in the class you're potentially going to synchronize on).
(Personally I wish that both Java and .NET hadn't gone down the "every object has an associated monitor" route, but that's a rant for a different day.)

Example 1 is much better. Since xList are final, they are great for synchronization. There is no need for extra lock objects, unnecessarily complicating code and consuming memory. Only make sure the list itself is never exposed to the outside world breaking encapsulation and thread safety.
However consider:
CopyOnWriteArrayList
Collections.synchronizedList() - and see also: Java synchronized block vs. Collections.synchronizedMap

Let's put it this way: the second approach uses more code -- what does that extra code buy you? As far as concurrency, the two are exactly the same, so it must be some other aspect from the bigger picture of your app design.

Even if you're sure the object you are doing the lock will never change I find it more reassuring to use special object just for locking. It makes it more transparent. If the class was to be significantly expanded and/or modified in the future by someone else he might find a reason to make xList non-final without noticing that it's used for locking. This could quickly lead to problems. Thread safety is not trivial and can grow more complex when code evolves so make it as clear and as safe as possible. Cost of having a separate object just for locking is small compared to the cost of diagnosing problems with thread-safety.

Related

Immutable-but-refreshable collections?

A common pattern I am encountering is a need to refresh a collection like a List or a HashMap from a database but don't want values added or removed from it in between refreshes.
I recently discovered the ImmutableList and ImmutableMap in Google's Guava library which I like a lot. But I cannot do a "clearAll()" on these types nor repopulate them. But I like that they are immutable beyond that.
So if I wanted to enforce this pattern of "only make mutable on a database refresh", I guess I would have to use a volatile variable each time? Or is there a better pattern? This can be in a multithreaded environment too, and I would ensure there's no race conditions on the refresh();
public class MarketManager {
private volatile ImmutableList<Market> markets = null;
private MarketManager() {
}
public void refresh() {
marketList = //build a new immutable market list
}
public static MarketManager getInstance() {
MarketManager marketManager = new MarketManager();
marketManager.refresh();
return marketManager;
}
}
Here is how you could code your class so that you use Collections.unmodifiableList():
public class MarketManager {
private volatile List<Market> markets = Collections.emptyList();
private MarketManager() {
}
public void refresh() {
marketList = //build a new market list
}
public List<Market> getMarkets() {
return Collections.unmodifiableList(markets);
}
// ...
}
Collections.unmodifiableList() simply wraps any List implementation so that all mutation operations are "disabled" (that is, they throw an exception).
I think you're trying to mix together two concepts: unmodifiable objects and immutable objects.
Unmodifiable objects are objects that YOU cannot modify. However, they can be changed "under you" by other actors. Such objects are useful when you need to control access to your object's internal state. However, they are not useful for thread safety or optimization.
Immutable objects are truly immutable. Once created, they cannot be changed. Not by you, not by anyone. They offer all the advantages of unmodifiable objects, plus they permit optimizations and guarantee thread safety.
What you're proposing will turn an immutable collection (created and frozen) into an unmodifiable one (I can't change it, but it can be refreshed from the DB). Just use unmodifiable collection framework from Java, no need to chang ethe Guava immutable collections.

Java: Should I construct lightweight objects each time or cache instance?

During code review, a colleague of mine looked at this piece of code:
public List<Item> extractItems(List<Object[]> results) {
return Lists.transform(results, new Function<Object[], Item>() {
#Override
public Item apply(Object[] values) {
...
}
});
}
He suggests changing it to this:
public List<Item> extractItems(List<Object[]> results) {
return Lists.transform(results, getTransformer());
}
private Function<Object[], Item> transformer;
private Function<Object[], Item> getTransformer() {
if(transformer == null) {
transformer = new Function<Object[], Item>() {
#Override
public Item apply(Object[] values) {
...
}
};
}
return transformer;
}
So we are looking at taking the new Function() construction, and moving it over to be a member variable and re-used next time.
While I understand his logic and reasoning, I guess I'm not sold that I should do this for every possible object that I create that follows this pattern. It seems like there would be some good reasons not to do this, but I'm not sure.
What are your thoughts? Should we always cache duplicately created objects like this?
UPDATE
The Function is a google guava thing, and holds no state. A couple people have pointed out the non-thread-safe aspect of this change, which is perfectly valid, but isn't actually a concern here. I'm more asking about the practice of constructing vs caching small objects, which is better?
Your colleague's proposal is not thread safe. It also reeks of premature optimization. Is the construction of a Function object a known (tested) CPU bottleneck? If not, there's no reason to do this. It's not a memory problem - you're not keeping a reference, so GC will sweep it away, probably from Eden.
As already said, it's all premature optimization. The gain is probably not measurable and the whole story should be forgotten.
However, with the transformer being stateless, I'd go for it for readability reasons. Anonymous functions as an argument rather pollute the code.
Just drop the lazy initialization - you're gonna use the transformer whenever you use the class, right? (*) So put it in a static final field and maybe you can reuse it somewhere else.
(*) And even if not, creating and holding a cheap object during the whole application lifetime doesn't matter.

Determining synchronization scope?

in trying to improve my understanding on concurrency issues, I am looking at the following scenario (Edit: I've changed the example from List to Runtime, which is closer to what I am trying):
public class Example {
private final Object lock = new Object();
private final Runtime runtime = Runtime.getRuntime();
public void add(Object o) {
synchronized (lock) { runtime.exec(program + " -add "+o); }
}
public Object[] getAll() {
synchronized (lock) { return runtime.exec(program + " -list "); }
}
public void remove(Object o) {
synchronized (lock) { runtime.exec(program + " -remove "+o); }
}
}
As it stands, each method is by thread safe when used standalone. Now, what I'm trying to figure out is how to handle where the calling class wishes to call:
for (Object o : example.getAll()) {
// problems if multiple threads perform this operation concurrently
example.remove(b);
}
But as noted, there is no guarantee that the state will be consistent between the call to getAll() and the calls to remove(). If multiple threads call this, I'll be in trouble. So my question is - How should I enable the developer to perform the operation in a thread safe manner? Ideally I wish to enforce the thread safety in a way that makes it difficult for the developer to avoid/miss, but at the same time not complicated to achieve. I can think of three options so far:
A: Make the lock 'this', so the synchronization object is accessible to calling code, which can then wrap the code blocks. Drawback: Hard to enforce at compile time:
synchronized (example) {
for (Object o : example.getAll()) {
example.remove(b);
}
}
B: Place the combined code into the Example class - and benefit from being able to optimize the implementation, as in this case. Drawback: Pain to add extensions, and potential mixing unrelated logic:
public class Example {
...
public void removeAll() {
synchronized (lock) { Runtime.exec(program + " -clear"); }
}
}
C: Provide a Closure class. Drawback: Excess code, potentially too generous of a synchronization block, could in fact make deadlocks easier:
public interface ExampleClosure {
public void execute(Example example);
}
public Class Example {
...
public void execute(ExampleClosure closure) {
synchronized (this) { closure.execute(this); }
}
}
example.execute(new ExampleClosure() {
public void execute(Example example) {
for (Object o : example.getAll()) {
example.remove(b);
}
}
}
);
Is there something I'm missing? How should synchronization be scoped to ensure the code is thread safe?
Use a ReentrantReadWriteLock which is exposed via the API. That way, if someone needs to synchronize several API calls, they can acquire a lock outside of the method calls.
In general, this is a classic multithreaded design issue. By synchronizing the data structure rather than synchronizing concepts that use the data structure, it's hard to avoid the fact that you essentially have a reference to the data structure without a lock.
I would recommend that locks not be done so close to the data structure. But it's a popular option.
A potential technique to make this style work is to use an editing tree-walker. Essentially, you expose a function that does a callback on each element.
// pointer to function:
// - takes Object by reference and can be safely altered
// - if returns true, Object will be removed from list
typedef bool (*callback_function)(Object *o);
public void editAll(callback_function func) {
synchronized (lock) {
for each element o { if (callback_function(o)) {remove o} } }
}
So then your loop becomes:
bool my_function(Object *o) {
...
if (some condition) return true;
}
...
editAll(my_function);
...
The company I work for (corensic) has test cases extracted from real bugs to verify that Jinx is finding the concurrency errors properly. This type of low level data structure locking without higher level synchronization is pretty common pattern. The tree editing callback seems to be a popular fix for this race condition.
I think everyone is missing his real problem. When iterating over the new array of Object's and trying to remove one at a time the problem is still technically unsafe (though ArrayList implantation would not explode, it just wouldnt have expected results).
Even with CopyOnWriteArrayList there is the possibility that there is an out of date read on the current list to when you are trying to remove.
The two suggestions you offered are fine (A and B). My general suggestion is B. Making a collection thread-safe is very difficult. A good way to do it is to give the client as little functionality as possible (within reason). So offering the removeAll method and removing the getAll method would suffice.
Now you can at the same time say, 'well I want to keep the API the way it is and let the client worry about additional thread-safety'. If thats the case, document thread-safety. Document the fact that a 'lookup and modify' action is both non atomic and non thread-safe.
Today's concurrent list implementations are all thread safe for the single functions that are offered (get, remove add are all thread safe). Compound functions are not though and the best that could be done is documenting how to make them thread safe.
I think j.u.c.CopyOnWriteArrayList is a good example of similar problem you're trying to solve.
JDK had a similar problem with Lists - there were various ways to synchronize on arbitrary methods, but no synchronization on multiple invocations (and that's understandable).
So CopyOnWriteArrayList actually implements the same interface but has a very special contract, and whoever calls it, is aware of it.
Similar with your solution - you should probably implement List (or whatever interface this is) and at the same time define special contracts for existing/new methods. For example, getAll's consistency is not guaranteed, and calls to .remove do not fail if o is null, or isn't inside the list, etc. If users want both combined and safe/consistent options - this class of yours would provide a special method that does exactly that (e.g. safeDeleteAll), leaving other methods close to original contract as possible.
So to answer your question - I would pick option B, but would also implement interface your original object is implementing.
From the Javadoc for List.toArray():
The returned array will be "safe" in
that no references to it are
maintained by this list. (In other
words, this method must allocate a new
array even if this list is backed by
an array). The caller is thus free to
modify the returned array.
Maybe I don't understand what you're trying to accomplish. Do you want the Object[] array to always be in-sync with the current state of the List? In order to achieve that, I think you would have to synchronize on the Example instance itself and hold the lock until your thread is done with its method call AND any Object[] array it is currently using. Otherwise, how will you ever know if the original List has been modified by another thread?
You have to use the appropriate granularity when you choose what to lock. What you're complaining about in your example is too low a level of granularity, where the lock doesn't cover all the methods that have to happen together. You need to make methods that combine all the actions that need to happen together within the same lock.
Locks are reentrant so the high-level method can call low-level synchronized methods without a problem.

What's the preferred way to assign a collection from a parameter?

I have this class:
public MyClass {
public void initialize(Collection<String> data) {
this.data = data; // <-- Bad!
}
private Collection<String> data;
}
This is obviously bad style, because I'm introducing a shared mutable state. What's the preferred way to handle this?
Ignore it?
Clone the collection?
...?
EDIT: To clarify why this is bad, imagine this:
MyClass myObject = new MyClass();
List<String> data = new ArrayList<String>();
myObject.initialize(data); // myObject.data.size() == 0
data.add("Test"); // myObject.data.size() == 1
Just storing the reference poses a way to inject data into the private field myObject.data, although it should be completely private.
Depending on the nature of MyClass this could have serious impacts.
The best way is to deep clone the parameter. For performance reasons, this is usually not possible. On top of that, not all objects can be cloned, so deep copying might throw exceptions and cause all kinds of headache.
The next best way would be a "copy-on-write" clone. There is no support for this in the Java runtime.
If you think that it's possible someone mutates the collection, do a shallow copy using the copy constructor:
this.data = new HashSet<String> (data);
This will solve your problem (since String is immutable) but it will fail when the type in the set is mutable.
Another solution is to always make the sets immutable as soon as you store them somewhere:
Set<String> set = ...
...build the set...
// Freeze the set
set = Collections.unmodifiableSet(set);
// Now you can safely pass it elsewhere
obj.setData (set);
The idea here is turn collections into "value objects" as soon as possible. Anyone who wants to change the collection must copy it, change it and then save it back.
Within a class, you can keep the set mutable and wrap it in the getter (which you should do anyway).
Problems with this approach: Performance (but it's probably not as bad as you'd expect) and discipline (breaks if you forget it somewhere).
Null check (if you want to restrict null)
Either defensive copy (if you don't want shared state)
or as you did (if a live view on data is useful)
Depends heavily on your requirements.
Edited:
Ignoring should be no option. Silent fail is, well... a debugging nightmare.
public class Foo {
private final Collection collection = new ArrayList();
public void initialise(final Collection collection) {
this.collection.addAll(collection);
}
}
Sorry for not addressing your concern directly, but I would never directly pass a Collection to a setXxx() bean setter method. Instead, I would do:
private final List<MyClass> theList;
public void addXxx(MyClass item) { ... }
public void removeXxx(MyClass item) { ... } // or index.
public void Iterator<MyClass> iterateXxx() {
return Collections.unmodifiableList(theList).iterator();
}
I would go for defensive copying / deep cloning only if I am sure there would be no side effects from using it, and as for the speed, I wouldn't concern myself with it, since in business applications reliability has 10 times more priority than speed. ;-)
An idea will be to pass the data as a String array and create the Set inside MyClass. Of course MyClass should test that the input data is valid. I believe that this is a good practice anyway.
If both the caller of MyClass and MyClass itself actually work with a Set<String>, then you could consider cloning the collection. The Set however needs to be constructed somehow. I would prefer to move this responsibility to MyClass.

In Java critical sections, what should I synchronize on?

In Java, the idiomatic way to declare critical sections in the code is the following:
private void doSomething() {
// thread-safe code
synchronized(this) {
// thread-unsafe code
}
// thread-safe code
}
Almost all blocks synchronize on this, but is there a particular reason for this? Are there other possibilities? Are there any best practices on what object to synchronize on? (such as private instances of Object?)
As earlier answerers have noted, it is best practice to synchronize on an object of limited scope (in other words, pick the most restrictive scope you can get away with, and use that.) In particular, synchronizing on this is a bad idea, unless you intend to allow the users of your class to gain the lock.
A particularly ugly case arises, though, if you choose to synchronize on a java.lang.String. Strings can be (and in practice almost always are) interned. That means that each string of equal content - in the ENTIRE JVM - turns out to be the same string behind the scenes. That means that if you synchronize on any String, another (completely disparate) code section that also locks on a String with the same content, will actually lock your code as well.
I was once troubleshooting a deadlock in a production system and (very painfully) tracked the deadlock to two completely disparate open source packages that each synchronized on an instance of String whose contents were both "LOCK".
First, note that the following code snippets are identical.
public void foo() {
synchronized (this) {
// do something thread-safe
}
}
and:
public synchronized void foo() {
// do something thread-safe
}
do exactly the same thing. No preference for either one of them except for code readability and style.
When you do synchronize methods or blocks of code, it's important to know why you are doing such a thing, and what object exactly you are locking, and for what purpose.
Also note that there are situations in which you will want to client-side synchronize blocks of code in which the monitor you are asking for (i.e. the synchronized object) is not necessarily this, like in this example :
Vector v = getSomeGlobalVector();
synchronized (v) {
// some thread-safe operation on the vector
}
I suggest you get more knowledge about concurrent programming, it will serve you a great deal once you know exactly what's happening behind the scenes. You should check out Concurrent Programming in Java, a great book on the subject. If you want a quick dive-in to the subject, check out Java Concurrency # Sun
I try to avoid synchronizing on this because that would allow everybody from the outside who had a reference to that object to block my synchronization. Instead, I create a local synchronization object:
public class Foo {
private final Object syncObject = new Object();
…
}
Now I can use that object for synchronization without fear of anybody “stealing” the lock.
Just to highlight that there are also ReadWriteLocks available in Java, found as java.util.concurrent.locks.ReadWriteLock.
In most of my usage, I seperate my locking as 'for reading' and 'for updates'. If you simply use a synchronized keyword, all reads to the same method/code block will be 'queued'. Only one thread can access the block at one time.
In most cases, you never have to worry about concurrency issues if you are simply doing reading. It is when you are doing writing that you worry about concurrent updates (resulting in lost of data), or reading during a write (partial updates), that you have to worry about.
Therefore a read/write lock makes more sense to me during multi-threaded programming.
You'll want to synchronize on an object that can serve as a Mutex. If the current instance (the this reference) is suitable (not a Singleton, for instance), you may use it, as in Java any Object may serve as the Mutex.
In other occasions, you may want to share a Mutex between several classes, if instances of these classes may all need access to the same resources.
It depends a lot on the environment you're working in and the type of system you're building. In most Java EE applications I've seen, there's actually no real need for synchronization...
Personally, I think the answers which insist that it is never or only rarely correct to sync on this are misguided. I think it depends on your API. If your class is a threadsafe implementation and you so document it, then you should use this. If the synchronization is not to make each instance of the class as a whole threadsafe in the invocation of it's public methods, then you should use a private internal object. Reusable library components often fall into the former category - you must think carefully before you disallow the user to wrap your API in external synchronization.
In the former case, using this allows multiple methods to be invoked in an atomic manner. One example is PrintWriter, where you may want to output multiple lines (say a stack trace to the console/logger) and guarantee they appear together - in this case the fact that it hides the sync object internally is a real pain. Another such example are the synchronized collection wrappers - there you must synchronize on the collection object itself in order to iterate; since iteration consists of multiple method invocations you cannot protect it totally internally.
In the latter case, I use a plain object:
private Object mutex=new Object();
However, having seen many JVM dumps and stack traces that say a lock is "an instance of java.lang.Object()" I have to say that using an inner class might often be more helpful, as others have suggested.
Anyway, that's my two bits worth.
Edit: One other thing, when synchronizing on this I prefer to sync the methods, and keep the methods very granular. I think it's clearer and more concise.
Synchronization in Java often involves synchronizing operations on the same instance. Synchronizing on this then is very idiomatic since this is a shared reference that is automatically available between different instance methods (or sections of) in a class.
Using another reference specifically for locking, by declaring and initializing a private field Object lock = new Object() for example, is something I never needed or used. I think it is only useful when you need external synchronization on two or more unsynchronized resources inside an object, although I would always try to refactor such a situation into a simpler form.
Anyway, implicit (synchronized method) or explicit synchronized(this) is used a lot, also in the Java libraries. It is a good idiom and, if applicable, should always be your first choice.
On what you synchronize depends on what other threads that might potentially get into conflict with this method call can synchronize.
If this is an object that is used by only one thread and we are accessing a mutable object which is shared between threads, a good candidate is to synchronize over that object - synchronizing on this has no point since another thread that modifies that shared object might not even know this, but does know that object.
On the other hand synchronizing over this makes sense if many threads call methods of this object at the same time, for instance if we are in a singleton.
Note that a syncronized method is often not the best option, since we hold a lock the whole time the method runs. If it contains timeconsuming but thread safe parts, and a not so time consuming thread-unsafe part, synchronizing over the method is very wrong.
Almost all blocks synchronize on this, but is there a particular reason for this? Are there other possibilities?
This declaration synchronizes entire method.
private synchronized void doSomething() {
This declaration synchronized a part of code block instead of entire method.
private void doSomething() {
// thread-safe code
synchronized(this) {
// thread-unsafe code
}
// thread-safe code
}
From oracle documentation page
making these methods synchronized has two effects:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Are there other possibilities? Are there any best practices on what object to synchronize on? (such as private instances of Object?)
There are many possibilities and alternatives to synchronization. You can make your code thread safe by using high level concurrency APIs( available since JDK 1.5 release)
Lock objects
Executors
Concurrent collections
Atomic variables
ThreadLocalRandom
Refer to below SE questions for more details:
Synchronization vs Lock
Avoid synchronized(this) in Java?
the Best Practices is to create an object solely to provide the lock:
private final Object lock = new Object();
private void doSomething() {
// thread-safe code
synchronized(lock) {
// thread-unsafe code
}
// thread-safe code
}
By doing this you are safe, that no calling code can ever deadlock your method by an unintentional synchronized(yourObject) line.
(Credits to #jared and #yuval-adam who explained this in more details above.)
My guess is that the popularity of using this in tutorials came from early Sun javadoc: https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
Synchronization includes 3 parts: Atomicity, Visibility and Ordering
Synchronized block is very coarse level of synchronization. It enforces visibility and ordering just as what you expected. But for atomicity, it does not provide much protection. Atomicity requires global knowledge of the program rather than local knowledge. (And that makes multi-threading programming very hard)
Let's say we have a class Account having method deposit and withdraw. They are both synchronized based on a private lock like this:
class Account {
private Object lock = new Object();
void withdraw(int amount) {
synchronized(lock) {
// ...
}
}
void deposit(int amount) {
synchronized(lock) {
// ...
}
}
}
Considering we need to implement a higher-level class which handles transfer, like this:
class AccountManager {
void transfer(Account fromAcc, Account toAcc, int amount) {
if (fromAcc.getBalance() > amount) {
fromAcc.setBalance(fromAcc.getBalance() - amount);
toAcc.setBalance(toAcc.getBalance + amount);
}
}
}
Assuming we have 2 accounts now,
Account john;
Account marry;
If the Account.deposit() and Account.withdraw() are locked with internal lock only. That will cause problem when we have 2 threads working:
// Some thread
void threadA() {
john.withdraw(500);
}
// Another thread
void threadB() {
accountManager.transfer(john, marry, 100);
}
Because it is possible for both threadA and threadB run at the same time. And thread B finishes the conditional check, thread A withdraws, and thread B withdraws again. This means we can withdraw $100 from John even if his account has no enough money. This will break atomicity.
You may propose that: why not adding withdraw() and deposit() to AccountManager then? But under this proposal, we need to create a multi-thread safe Map which maps from different accounts to their locks. We need to delete the lock after execution (otherwise will leak memory). And we also need to ensure no other one accesses the Account.withdraw() directly. This will introduce a lots of subtle bugs.
The correct and most idiomatic way is to expose the lock in the Account. And let the AccountManager to use the lock. But in this case, why not just use the object itself then?
class Account {
synchronized void withdraw(int amount) {
// ...
}
synchronized void deposit(int amount) {
// ...
}
}
class AccountManager {
void transfer(Account fromAcc, Account toAcc, int amount) {
// Ensure locking order to prevent deadlock
Account firstLock = fromAcc.hashCode() < toAcc.hashCode() ? fromAcc : toAcc;
Account secondLock = fromAcc.hashCode() < toAcc.hashCode() ? toAcc : fromAcc;
synchronized(firstLock) {
synchronized(secondLock) {
if (fromAcc.getBalance() > amount) {
fromAcc.setBalance(fromAcc.getBalance() - amount);
toAcc.setBalance(toAcc.getBalance + amount);
}
}
}
}
}
To conclude in simple English, private lock does not work for slightly more complicated multi-threaded program.

Categories