Loading...

How to use wait, notify and notifyAll in Java - Producer Consumer Example

You can use wait, notify and notifyAll methods to communicate between threads in Java. For example, if you have two threads running in your program e.g.Producer and Consumer then producer thread can communicate to consumer that it can start consuming now because there are items to consume in queue. Similarly a consumer thread can tell producer that it can also start putting items now because there is some space in queue, which is created as a result of consumption. A thread can use wait() method to pause and do nothing depending upon some condition. For example, in producer consumer problem, producer thread should wait if queue is full and consumer thread should wait if queue is empty. If some thread is waiting for some condition to become true, you can use notify and notifyAll methods to inform them that condition is now changed and they can wake up. Both notify() and notifyAll() method sends notification but notify sends notification to only one of the waiting thread, no guarantee which thread will receive notification and notifyAll() sends notification to all threads. So if only one thread is waiting on an object lock, also known as monitor then both notify and notifyAll wil send notification to it. If multiple threads are waiting on a monitor then notify will only inform one of the lucky thread and rest will not receive any notification, but notifyAll will inform all threads. In this Java multi-threading tutorial you will learn how to use wait, notify and notifyAll() method in Java to implement inter thread communication by solving producer consumer problem. BTW, if you are serious about mastering concurrency and multi-threading, I strongly suggest you to read Java Concurrency in Practice by Brian Goetz, without reading that book your journey to Java multi-threading is not complete. Its probably one of the most recommended book to Java developers.

Java Lock and Condition Example using Producer Consumer Solution

You can also solve producer consumer problem by using new lock interface and condition variable instead of using synchronized keyword and wait and notify methods.  Lock provides an alternate way to achieve mutual exclusion and synchronization in Java. Advantage of Lock over synchronized keyword is well known, explicit locking is much more granular and powerful than synchronized keyword, for example, scope of lock can range from one method to another but scope of synchronized keyword cannot go beyond one method. Condition variables are instance of java.util.concurrent.locks.Condition class, which provides inter thread communication methods similar to wait, notify and notifyAll e.g. await(), signal() and signalAll(). So if one thread is waiting on a condition by calling condition.await() then once that condition changes, second thread can call condition.signal() or condition.signalAll() method to notify that its time to wake-up, condition has been changed. Though Lock and Condition variables are powerful they are slightly difficult to use for first timers. If you are used to locking using synchronized keyword, you will using Lock painful because now it becomes developer's responsibility to acquire and release lock. Anyway, you can follow code idiom shown here to use Lock to avoid any concurrency issue. In this article, you will learn how to use Lock and Condition variables in Java by solving classic Producer Consumer problem. In order to deeply understand these new concurrency concepts, I also suggest to take a look at Java 7 Concurrency Cookbook, Its one of the best book in Java concurrency with some good non trivial examples.

How to use Callable and Future in Java? Example

Callable interface was added in Java 5 to complement existing Runnable interface, which is used to wrap a task and pass it to a Thread or thread pool for asynchronous execution. Callable actually represent an asynchronous computation, whose value is available via Future object. All the code which needs to be executed asynchronously goes into call() method. Callable is also a single abstract method type (SAM type), so it can be used along with lambda expression on Java 8. Both Callable and Future are parametric type and can be used to wrap classes like Integer, String or anything else. When you pass a Callable to thread pool, it choose one thread and execute the Callable. It immediately return a Future object which promises to hold result of computation once done. You can then call get() method of Future, which will return result of computation or block if Computation is not complete. If you don't like indefinite blocking then you can also use overloaded get() method with timeout. Future also allows you to cancel the task if its not started or interrupt if its started. We will see, how we can calculate factorial of large number using Callable and Future in Java. BTW, if you are serious about mastering concurrency API of Java, I suggest you to also take a look at one of the best book on the subject, Java Concurrency in Practice by Brian Goetz. It is one of the book I keep refer whenever I have a doubt or want to refresh my knowledge.

Top 10 Java Multithreading and Concurrency Best Practices

Writing concurrent code is hard and and testing correctness with concurrency is even harder. Though Java programming language provides lots of synchronization and concurrency support from language to API level, it's eventually comes to individual's diligent and expertise to write bug free Java concurrency code. These Java concurrency and multi-threading best practices are collection of some well known tips, which helps you to write better concurrency code in Java. Some of you, may be familiar with these tips, it's often worth to revise them in couple of years. These Java multi-threading and concurrency tips are from my own learning and usage, and also inspired by reading books like Effective Java and Java Concurrency in Practice in particular. I suggest reading Java Concurrency Practice two times to every Java developer, yes, you heard it correctly, TWO times. Concurrency is confusing and difficult to comprehend, much like Recursion to few programmers; and in one reading, you might not get all of it.

How to use Future and FutureTask in Java Concurrency with Example

Future and FutureTask in Java allows you to write asynchronous code. Future is a general concurrency abstraction, also known as promise, which promises to return a result in future. In asynchronous programming, main thread doesn't wait for any task to finished, rather it hand over the task to workers and move on. One way of aynchronous processing is using callback methods. Future is another way to write asynchronous code. By using Future and FutureTask, you can write method which does long computation but return immediately. Those method, instead of returning result, return a Future object. You can later get result by calling Future.get() method, which will return object of type T, where T is what Future object is holding . One example of Future is submit() method of ExecutorService, which immediately return a Future object. By the way, Future and FutureTask are available in java.util.concurreent package from Java 1.5. Also, Future is and interface and FutureTask is an implementation or RunnableFuture, which can be used as Runnable interface, thus, can be passed to ExecutorService. In this Java concurrency tutorial, we will learn how to use Future and FutureTask in Java.

How to Use Locks in Multi-threaded Java Program

Many Java programmers confused themselves like hell while writing multi-threaded Java programs e.g. where to synchronized? Which Lock to use? What Lock to use etc. I often receive request to explain about how to use Locks in Java, so I thought to write a simple Java program, which is multi-threaded and uses rather new Lock interface. Remember Lock is your tool to guard shared resource which can be anything e.g. database, File system, a Prime number Generator or a Message processor. Before using Locks in Java program, it’s also better to learn some basics. Lock is an interface from java.util.concurrent package. It was introduced in JDK 1.5 release as an alternative of synchronized keyword. If you have never written any multi-threading program, then I suggest first start with synchronized keyword because it’s easier to use them. Once you are familiar with working of multi-threading program e.g. How threads share data, how inter thread communication works, you can start with Lock facility. As I told you Lock is an interface, so we cannot use it directly, instead we need to use its implementation class. Thankfully Java comes with two implementation of java.util.concurrent.locks.Lock interface, ReentrantLock and ReentrantReadWriteLock, later provides two more inner implementation known as ReentrantReadWriteLock.ReadLock and ReentrantReadWriteLock.WriteLock. For our simple multi-threaded Java program's purpose ReentrantLock is enough.

Common Multi-threading Mistakes in Java - Calling run() instead of start()

Writing multi-threaded and concurrent programs is not easy, not even in Java.  Even senior developers, including myself, make mistakes while writing concurrent Java applications. This is also one of the trickiest area of Java programming language, where misconceptions outnumbers concepts. Considering amount of misconception an average Java programmers has about multi-threading and concurrency, I thought to start a new series about common multi-threading mistakes done by Java programmers; what is better way to learn from common real word mistakes. Learning from mistakes has another name Experience, but if you only learn from your mistakes then there is only limited things you can learn, but if you learn from other peoples mistake, you can learn much more in short span of time. Have you ever thought, Why writing multi-threaded code is difficult? IMHO, primarily reason for this is that it multi-threading makes it hard for a code to speak for itself. Programmer read code sequentially to understand how it's executed, but it is only correct if one and only one thread is executing it. That's why Single threaded code are easy to read and debug. As soon as two threads comes into picture, It become very difficult to make prediction about how your code behave, especially in the absent of any synchronization rules e.g. rules enforced by Java Memory Model. Without JMM you can not make correct prediction about your code in a multi-threaded environment, because it's possible for one thread to stop at arbitrary point and another thread at different point. Situation becomes even more tricky if those threads are sharing data between them e.g. in form of objects, a poorly written multi-threaded program can cause deadlock, race condition and responsiveness issues, which will prevent a Java application to fulfil it's promise. I hope, in this series we can learn from each other's mistake and take a step forward on writing correct multi-threaded application in Java.