Any practical example of LockSupport & AbstractQueuedSynchronizer use? - java

Guys, can anyone give a simple practical example of LockSupport & AbstractQueuedSynchronizer use? Example given in javadocs is quite strained.
Usage of Semaphore permits is understood by me.
Thanks for any response.

If youre talking about using a locking mechanism (or even sync barriers) just use a java.util.concurrent.Lock. The obvious suggestion is to user a ReentrantLock which delegates to a Synch. The synch is an AQS which in turn uses LockSupport.
Its all done under the covers for you.
Edit:
No let's go over the practical uses of AbstractQueuedSynchronizer (AQS).
Concurrency constructs though can be very different in their usage all can have the same underlying functions.
I.e. Under some condition park this thread. Under some other condition wake a thread up.
This is a very broad set of instructions but makes it obvious that most concurrency structures would need some common functionality that would be able to handle those operations for them. Enter AQS. There are five major synchronization barriers.
ReentrantLock
ReadLock
WriteLock
Semaphore
CountDownLatch
Now, all these five structures have very different set of rules when using them. A CountdownLatch can allow many threads to run at the same time but forces one (or more) threads to wait until at least n number of threads count down on said latch.
ReentrantLock forces only one thread at a time to enter a critical section and queues up all other threads to wait for it to completed.
ReadLock allows any number of reading threads into the critical section until a write lock is acquiered.
The examples can go on, but the big picture here is they all use AQS. This is because they are able to use the primitive functions that AQS offers and implements more complex functionality on top of it. AQS allows you to park unpark and wake up threads ( interruptibly if need be) but in such a way that you can support many complex functions.

they are not meant for direct use in client code; more for helping building new concurrent classes.

AQS is a wonderful class for building concurrency primitives – but it is complex and requires a bit of study to use it properly. I have used it for a few things like lazy initialisation and a simple fast reusable latch.
As complex as it is, I don't think AQS is particularly vague, it has excellent javadocs describing how to use it properly.

2.7 release of Disruptor uses LockSupport.parkNanos instead of Thread.sleep to reduce latency:
http://code.google.com/p/disruptor/

AFAIK, AbstractQueuedSynchronizer is used to manage state transitions. The JDK uses it to extend Sync, an internal class for java.util.concurrent.FutureTask. The Sync class manages the states (READY, RUNNING, RAN, and CANCELLED) of FutureTask and the transitions between them.
This allows, as you may know, FutureTask to block on FutureTask.get() until the RAN state is reached, for example.

Related

Can Threadpoolexecutor switch its blockingQueue after start?

Can Threadpoolexecutor change its blockingqueue after start? I am using multiple threadpoolexecutors in my process. I don't want to breach the maximum number of threads beyond a certain number in my process. That is why I thought of the idea of switching blockingqueue of my threadpool to a more busy blockingqueue. But I don't see any function in ThreadpoolExecutor class which provides the facility of switching blockingqueues. What could be the reason behind this?
Apparently threadpoolexecutor gives access to its blockingqueue. I can achieve the same behavior by transfering tasks from one queue to another queue.
Immutable objects are usually favoured in modern programming practices. It usually make things... Simpler in regards to object model growth and future enhancements (And no, I don't consider python's approach of "Let's all be responsible adults" as modern for the sake of the argument).
As for solving your problem you.could perhaps pass a smart "Delegating" BlockingQueue implementation that'll implement the standard interface but back it with some queue switching mechanism, controlled internally or externally as your specification requires

in multithreaded programming does synchronization strip the benefits of concurrent executions

I have a dilemma regarding the use of multithreading in the application I am working on. I have a workflow in which the state of the object changes, which presents no issues for single-threaded operation. However, In order to improve the performance, I am planning to use multiple threads.
It is my understanding that since the state is going to be shared among the threads, every thread must acquire a lock on the state before execution, so doesn't this defeat the purpose of multithreading? It seems like multiple threads won't produce any actual concurrency, so it wouldn't be any better than single threaded.
Is my analysis correct? If I am misunderstanding then would someone please clarify the concept?
The short answer: concurrency is hard. Real concurrency, with multiple concurrent writers, is really hard.
What you need to determine is what your actual consistency guarantees need to be. Does every reader need to be able to see every write, guaranteed? Then you'll be forced into linearizing all the threads somehow (e.g. using locks) -- your next effort should be to ensure you do as much work as possible outside of the lock, to keep the lock held for the shortest possible time.
One way to keep the lock held for the shortest possible time is to use a lock-free algorithm. Most lock-free algorithms are based on an atomic compare-and-set primitive, such as those provided by the java.util.concurrent.atomic package. These can be very high-performance, but designing a successful lock-free algorithm can be subtle. One simple kind of lock-free algorithm is to just build a new (immutable) state object and then atomically make it the "live" state, retrying in a loop if a different state was made live by another writer in the interim. (This approach is good enough for many applications, but it's vulnerable to livelock if you have too many writers.)
If you can get by with a looser consistency guarantee, then many other optimizations are possible. For example, you can use thread-local caches so that each thread sees its own view of the data and can be writing in parallel. Then you need to deal with the consequences of data being stale or inconsistent. Most techniques in this vein strive for eventual consistency: writes may not be visible to all readers immediately, but they are guaranteed to be visible to all readers eventually.
This is an active area of research, and a complete answer could fill a book (really, several books!). If you're just getting started in this area, I'd recommend you read Java Concurrency in Practice by Goetz et al, as it provides a good introduction to the subject and lots of practical advice about how to successfully build concurrent systems.
Your interpretation of the limits of multithreading and concurrency are correct. Since the state must be acquired and controlled by threads in order for them to perform work (and waiting when not working), you are essentially splitting the work of a single thread among multiple threads.
The best way to fix this is to adjust your program design to limit the size of the critical section. As we learned in my operating systems course with process synchronization,
only one critical section must be executing at any given time
The specific term critical section may not directly apply to Java concurrency, but it still illustrates the concept.
What does it mean to limit this critical section? For example, let's say you have a program managing a single bank account (unrealistic, but illustrates my point). If a lock on the account must be acquired by a thread for the balance to be updated, the basic option would be to have a single thread working on updating the balance at all times (without concurrency). The critical section would be the entire program. However, let's say there was also other logic to be executed, such as alerting other banks of the balance update. You could require the lock on the bank account state only while updating the balance, and not when alerting other banks, decreasing the size of critical section and allowing other threads to perform work by alerting other banks while one thread is updating the balance.
Please comment if this was unclear. Your seem to already understand the constraints of concurrency, but hopefully this will reveal possible steps towards implementing concurrency.
Your need is not totally clear but you guess well the limitations that multi threading may have.
Running parallel threads have a sense if some "relatively autonomous" tasks can be concurrently performed by distinct threads or group of threads.
If your scenario looks like : you start 5 threads and finally only a single thread is active while the others are waiting for a locking resource, using multithreading makes no sense and could even introduce an overhead because of cpu context switches.
I think that in your use case, the multithreading could be used for :
tasks that don't change the state
performing a task that changes the state if the task may be divided in multiple processing with a minimal set of instructions that may do profitable the multithreading use.
It is my understanding that since the state is going to be shared among the threads, every thread must acquire a lock on the state before execution, so doesn't this defeat the purpose of multithreading?
The short answer is "it depends". It is rare that you have a multithreaded application that has no shared data. So sharing data, even if it needs a full lock, doesn't necessarily defeat the performance improvements when making a single threaded application be multi-threaded.
The big question is what the frequency that the state needs to be updated by each thread. If the threads read in the state, do their concurrent processing which takes time, and then alter the state at the end then you may see performance gains. On the other hand, if every step in the processing needs to somehow be coordinated between threads then they may all spend them time contending for the state object. Reducing this dependence on shared state will then improve your multi-threaded performance.
There are also more efficient ways to update a state variable which can avoid locks. Something like the following pattern is used a lot:
private AtomicReference<State> sharedState;
...
// inside a thread processing loop
// do the processing job
while (true) {
State existingState = sharedState.get();
// create a new state object from the existing and our processing
State newState = updateState(state);
// if the application state hasn't changed, then update it
if (sharedState.compareAndSet(existingState, newState)) {
break;
}
// otherwise we need to get the new existing state and try again
}
One way to handle state changes is to have a coordinating thread. It is the only thread which reads from the state and generates jobs. As jobs finish they put updates to the state on a BlockingQueue which is then read by the coordinating thread which updates the state in turn. Then the processing threads don't have to all be contending for access to the shared state.
Imagine it this way :
Synchronization is blocking
Concurrency is parallelization
You don't have to use synchronization. You can use an Atomic reference object as a wrapper for your shared mutable state.
You can also use stamped locks which improves concurrency by allowing for optimistic reads. You may also use Accumulators to write concurrent code. These features are part of Java 8.
Another way to prevent synchronization is to use immutable objects which can be shared and published freely and need no synchronization. I should add that you should use immutable objects anyway regardless of concurrency for that makes your state space of the object easier to reason about

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.

What are the "Conventional Techniques" to avoid deadlock?

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.

Parallel-processing in Java; advice needed i.e. on Runnanble/Callable interfaces

Assume that I have a set of objects that need to be analyzed in two different ways, both of which take relatively long time and involve IO-calls, I am trying to figure out how/if I could go about optimizing this part of my software, especially utilizing the multiple processors (the machine i am sitting on for ex is a 8-core i7 which almost never goes above 10% load during execution).
I am quite new to parallel-programming or multi-threading (not sure what the right term is), so I have read some of the prior questions, particularly paying attention to highly voted and informative answers. I am also in the process of going through the Oracle/Sun tutorial on concurrency.
Here's what I thought out so far;
A thread-safe collection holds the objects to be analyzed
As soon as there are objects in the collection (they come a couple at a time from a series of queries), a thread per object is started
Each specific thread takes care of the initial pre-analysis preparations; and then calls on the analyses.
The two analyses are implemented as Runnables/Callables, and thus called on by the thread when necessary.
And my questions are:
Is this a reasonable scheme, if not, how would you go about doing this?
In order to make sure things don't get out of hand, should I implement a ThreadManager or some thing of that sort, which starts and stops threads, and re-distributes them when they are complete? For example, if i have 256 objects to be analyzed, and 16 threads in total, the ThreadManager assigns the first finished thread to the 17th object to be analyzed etc.
Is there a dramatic difference between Runnable/Callable other than the fact that Callable can return a result? Otherwise should I try to implement my own interface, in that case why?
Thanks,
You could use a BlockingQueue implementation to hold your objects and spawn your threads from there. This interface is based on the producer-consumer principle. The put() method will block if your queue is full until there is some more space and the take() method will block if the queue is empty until there are some objects again in the queue.
An ExecutorService can help you manage your pool of threads.
If you are awaiting a result from your spawned threads then Callable interface is a good idea to use since you can start the computation earlier and work in your code assuming the results in Future-s. As far as the differencies with the Runnable interface, from the Callable javadoc:
The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.
Some general things you need to consider in your quest for java concurrency:
Visibility is not coming by defacto. volatile, AtomicReference and other objects in the java.util.concurrent.atomic package are your friends.
You need to carefully ensure atomicity of compound actions using synchronization and locks.
Your idea is basically sound. However, rather than creating threads directly, or indirectly through some kind of ThreadManager of your own design, use an Executor from Java's concurrency package. It does everything you need, and other people have already taken the time to write and debug it. An executor manages a queue of tasks, so you don't need to worry about providing the threadsafe queue yourself either.
There's no difference between Callable and Runnable except that the former returns a value. Executors will handle both, and ready them the same.
It's not clear to me whether you're planning to make the preparation step a separate task to the analyses, or fold it into one of them, with that task spawning the other analysis task halfway through. I can't think of any reason to strongly prefer one to the other, but it's a choice you should think about.
The Executors provides factory methods for creating thread pools. Specifically Executors#newFixedThreadPool(int nThreads) creates a thread pool with a fixed size that utilizes an unbounded queue. Also if a thread terminates due to a failure then a new thread will be replaced in its place. So in your specific example of 256 tasks and 16 threads you would call
// create pool
ExecutorService threadPool = Executors.newFixedThreadPool(16);
// submit task.
Runnable task = new Runnable(){};;
threadPool.submit(task);
The important question is determining the proper number of threads for you thread pool. See if this helps Efficient Number of Threads
Sounds reasonable, but it's not as trivial to implement as it may seem.
Maybe you should check the jsr166y project.
That's probably the easiest solution to your problem.

Categories