What are the "Conventional Techniques" to avoid deadlock? - java

I saw the below statement in Java Specifications.
Programs where threads hold (directly
or indirectly) locks on multiple
objects should use conventional
techniques for deadlock avoidance,
creating higher-level locking
primitives that don't deadlock, if
necessary.
So, What are the "Conventional Techniques" to follow to avoid deadlock? I'm not pretty clear with this (not understood properly, explanation needed).

The most common technique is to acquire resources (locks) in some consistent well-defined order.
The following article by Brian Goetz might be helpful: http://www.javaworld.com/javaworld/jw-10-2001/jw-1012-deadlock.html
It's pretty old, but explains the issues well.

As a somewhat absract suggestion, an answer to this might be "Have a plan for handling locks and stick to it".
The danger of locking is where, in short, one thread holds lock A and is trying to get lock B, while another thread holds lock B and is trying to get lock A. As noted by another answer, the clasic way to avoid this is to get locks in a consistent order. However, a good discipline is to minimize the amount of work that your code does with a lock held. Any code that calls another function with a lock held is a potential problem: what if that other function tries to get another lock? What if someone else later modifies that function to get a lock? Try to form a clear pattern of what functions can be called with locks held, and what cannot, and make sure the comments in your code make this all clear.

Don't do locking! Seriously. We get immense performance (100k's of transactions at sub-millisecond latency) at my work by keeping all our business logic single threaded.

Related

Is it a bad practice to use pure lock() method in Java?

According to documentation:
void lock()
Acquires the lock.
If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired.
I'm using timed tryLock nearly everywhere, handling all what is expected - if timout ends, if it is interrupted, and so on.
But today, I've thought: is it bad/unsafe/dangerous to use pure lock()?
Examples showing it looking so cute and elegant - just lock and unlock in finally. I've googled, but haven't found answer about it being a bad practice.
It depends on how you use it inside of your code. If you just use it, only for lock and unlock, then you don't use any of the features it provides. So, you can merely fallback to intrinsic locks using the keyword synchronized. However, if you use timed lock and interruptible locking facilities, then it may be reasonable given your specific usecase warrants it. Intrinsic locks still have significant advantages over explicit locks. The notation is familiar and compact. Oftentimes, developers forget to call unlock on explicit locks, making it much more prone to errors.
Moreover, if you use condition objects you can still use either of them. If you have only one condition for the lock object, I would rather use intrinsic locks. The explicit locks become handy when you need to have multiple conditions for a given lock and need to use it without any interference from other conditions on the same lock.
In conclusion, it all depends on how you use it and whether your usecase warrants it.
There's nothing to say if its bad or good. If you need to handle critical blocks, you need to lock it.

how using Lock interface gives more performance over using synchronise keyword in concurrent applications design?

I was going through "Java Concurrency CookBook". In that author mentioned using Lock interface gives more performance over using synchronized keyword.Can any one tell how? Using the terms like stack-frame, ornumber of method calls.
Don't mind, please help me get rid of java concurrency concepts.
The raison d'etre for Lock and friends isn't that it is inherently faster than synchronized(), it is that it can be used in different ways that don't necessarily correspond to the lexical block structure, and also that it can offer more facilities such as read-write locks, counting semaphores, etc.
Whether a specific Lock implementation is actually faster than synchronized is a moot point and implementation-dependent. There is certainly no such claim in the Javadoc. Doug Leas's book[1] where it all started doesn't make any claim that I can see quickly stronger than 'often with better performance'.
[1]: Lea, Concurrent Programming in Java, 2nd edition, Addison Wesley 2000.
1 Synchronisation is the only culprit that leads to the problem of deadlock unlike lock which is free of deadlock issue.
2 In synchronisation , we don’t know after how much time a thread will get a chance after a previous thread has released the lock. This can lead to problem of starvation whereas incase of lock we have its implementing class reentrant lock which has one of its constructor which lets you pass fairness property as one of its argument that leta longest waiting thread get the chance to acquire the lock.
3 In synchronisation, if a thread is waiting for another thread, then the waiting thread won’t do any other activity which doesn’t require lock access but with lock interface there is a trylock() method with which you can try for access the lock and if you don’t get the lock you can perform other alternate tasks. This helps to improve the performance of the application .
4 There is no api to check how many threads are waiting for a particular lock whereas this is possible with lock interface implementation class ReentrantLock methods.
5 One can get better control of locks using lock interface with holdCount() method which is not found with synchronization.

Concurrency design principles in practice

I have a Results object which is written to by several threads concurrently. However, each thread has a specific purpose and owns certain fields, so that no data is actually modified by more than one thread. The consumer of this data will not try to read it until all of the writer threads are done writing it. Because I know this to be true, there is no synchronization on the data writes and reads.
There is a RunningState object associated with this Results object which serves to coordinate this work. All of its methods are synchronized. When a thread is done with its work on this Results object, it calls done() on the RunningState object, which does the following: decrements a counter, checks if the counter has gone to 0 (indicating that all writers are done), and if so, puts this object on a concurrent queue. That queue is consumed by a ResultsStore which reads all of the fields and stores data in the database. Before reading any data, the ResultsStore calls RunningState.finalizeResult(), which is an empty method whose sole purpose is to synchronize on the RunningState object, to ensure that writes from all of the threads are visible to the reader.
Here are my concerns:
1) I believe that this will work correctly, but I feel like I'm violating good design principles to not synchronize on the data modifications to an object that is shared by multiple threads. However, if I were to add synchronization and/or split things up so each thread only saw the data it was responsible for, it would complicate the code. Anyone who modifies this area had better understand what's going on in any case or they're likely to break something, so from a maintenance standpoint I think the simpler code with good comments explaining how it works is a better way to go.
2) The fact that I need to call this do-nothing method seems like an indication of wrong design. Is it?
Opinions appreciated.
This seems mostly right, if a bit fragile (if you change the thread-local nature of one field, for instance, you may forget to synchronize it and end up with hard-to-trace data races).
The big area of concern is in memory visibility; I don't think you've established it. The empty finalizeResult() method may be synchronized, but if the writer threads didn't also synchronize on whatever it synchronizes on (presumably this?), there's no happens-before relationship. Remember, synchronization isn't absolute -- you synchronize relative to other threads that are also synchronized on the same object. Your do-nothing method will indeed do nothing, not even ensure any memory barrier.
You somehow need to establish a happens-before relationship between each thread doing its writes, and the thread that eventually reads. One way to do this without synchronization is via a volatile variable, or an AtomicInteger (or other atomic classes).
For instance, each writer thread can invoke counter.incrementAndGet(1) on the object, and the reading thread can then check that counter.get() == THE_CORRECT_VALUE. There's a happens-before relationship between a volatile/atomic field being written and it being read, which gives you the needed visibility.
Your design is sound, but it can be improved if you are using a true concurrent queue since a concurrent queue from the java.util.concurrent package already guarantees a happens before relationship between the thread putting an item into the queue, and the thread taking an item out, so this precludes needing to call finalizeResult() in the taking thread (so no need for that "do nothing" method call).
From java.util.concurrent package description:
The methods of all classes in java.util.concurrent and its subpackages
extend these guarantees to higher-level synchronization. In
particular:
Actions in a thread prior to placing an object into any
concurrent collection happen-before actions subsequent to the access
or removal of that element from the collection in another thread.
The comments in another answer concerning using an AtomicInteger instead of synchronization are also wise (as using an AtomicInteger to do your thread counting will likely perform better than synchronization), just make sure to get the value of the count after the atomic decrement (e.g. decrementAndGet()) when comparing to 0 in order to avoid adding to the queue twice.
What you've described is indeed safe, but it also sounds, frankly, brittle and (as you note) maintenance could become an issue. Without sample code, it's really hard to tell what's really easiest to understand, so an already subjective question becomes frankly unanswerable. Could you ask a coworker for a code review? (Particularly one that's likely to have to deal with this pattern.) I'm going to trust you that this is indeed the simplest approach, but doing something like wrapping synchronized blocks around writes would increase safety now and in the future. That said, you obviously know your code better than I do.

Java uses object as monitor, isn't that object too heavy weight?

I read this in Java language Spec 17.1:
"Each object in Java is associated
with a monitor, which a thread can
lock or unlock."
Why necessarily? Doesn't that make java object too heavy weight? I've no idea why a Object like, say, a string, should be naturally a monitor!
EDIT:
I think it over and yes, Java has a keyword synchronized, because EVERY object could have a synchronized method, so it's necessary to associate EVERY object a Monitor.
But still this seems not a very good solution, usually you need more that one mutex for one class, except for that pojo classes that's really very simple.
There is some truth in your assumptions, in the classical book "Java Concurrency in Practice" (written by the gurus Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, Doug Lea) they write:
The fact that every object has a built-in lock is just a convenience
so that you needn't explicitly create lock objects. In retrospect,
this design decision was probably a bad one: not only can it be
confusing, but it forces JVM implementors to make tradeoffs between
object size and locking performance.
(chapter 2.4.: Guarding State with Locks)
Your fundamental problem is in assuming that every object has some sort of Monitor built into it, waiting for it to be used by some code. In reality, most objects are never used as a monitor, so the monitors don't have to be created until they are used. Rather than implementing this feature as every object having a private Monitor monitor field, think of it as being implemented as the JVM having a global HashMap<object, Monitor> monitors.
A possible implementation is this: Whenever a synchronized block is entered, the JVM looks up the synchronized object in the map (monitors). If it finds it, it gets the monitor to use. If it doesn't find it, it enters a critical section dedicated to the map. It then looks up the object again because another thread may have created it between the previous check and entering the critical section. If it's still not there, it creates the monitor for the synchronized object and leaves the critical section.
It's a pretty smart way to make virtually everything thread-safe. I think heavy weight is somewhat subjective; in Java, for example, the object only gains a notifiable wait queue, while specifying mutual exclusion is explicitly done with synchronize.
C# uses a similar method to enforce thread safety, so clearly MS also thought it was a pretty clever solution. The alternative is what? Hand-written semaphores and mutexes? In Java, that would be a nightmare, considering most production-level apps (i.e. servers, services, etc) have to be multi-threaded. Having the language do all that tough/boring stuff for you is kind of awesome.
Thread synchronization is necessary to ensure correct outcome as their may be racing condition.
Well, if it is not as heavy as a LCD or CRT monitor, it would be fine?
not that heavy in weight. objects are cheap.
I agree that the concept that any object can be a lock is quite confusing. many people thinks that synchronized(obj) protects the obj from being accessed concurrently. if we have separate locks from states, this misconception is less likely.
not text in java memory model shows any importance of using arbitrary object, or any object, as synchronization primitives. maybe it's economical design to use objects for this purpose.
it could as well use integers as locks. synchronized(493725) actually since each object is associated with an integer internally (its address), JVM probably does this. There's zero overhead for objects that are not being synchronized upon.
with java.util.concurrent classes, you don't ever need such synchronized(obj) any more, if you dislike it.

Implementing a global lock in Java

I have a relatively simple (perhaps stupid) question regarding synchronisation in Java.
I have synchronisation blocks that acquire locks on various objects throughout my code. In some scenarios, I want to acquire a global lock that subsumes every other synchronisation statement in my code.
Is there a fancy way to do this in Java without re-writing all the current synchronisation code?
For example,
Thread t1
synchronized (o1)
{
synchronized (o2)
{
// ...
}
}
Thread t2
synchronized (global_lock)
{
// ...
}
When thread t2 is inside the synchronised block, thread t1 should not be allowed to acquire the locks on o1 and o2.
Many thanks
if
It's not possible;
It's a really bad idea ( sorry ).
It's deadlock-prone, since it forces you to have a pre-determined locking order for all locks, no matter where they are.
Usually it's a good idea, if you need to acquire two locks, to always have a predetermined order:
synchronized(LOCK1) {
synchronized(LOCK2) {
}
}
But a global lock would need some sort of protocol - a global aquisition order - for all the locks. And that may not be possible at all. Most locks guard specific, self-contained, critical sections. They would be unaware that someone would 'yank' them out and aquire them and therefore would not be written to handle this situation.
So it's not possible, and you should be happy it's not. Although it seems to be the easy way out, it would bring a lot of pain.
Leaving aside the sheer horror of what you are proposing, you may want to consider using Aspect Oriented Programming (AOP) to "weave" additional synchronization/locking into your code at run time. You should be able to do this without writing the source.
There are many AOP options, including AspectJ and Spring AOP, which may be suitable depending on your environment.
The only feasible way to do it would be actually parse/modify/save (automatically) all the code. I did something like this for a project recently and it worked pretty good. We can talk more if you are interested.

Categories