In Java Multi-threading, in addition to using the Synchronize keyword to implement synchronous mutexes between threads, you can also use the new Retrantlock class in JDK1.5 to achieve the same effect. The extended functionality of the Retrantlock class is also more powerful, such as sniffing lock, multi-channel branch notification, and more flexible in use than synchronize.
With the condition object, Retrantlock can implement wait and Notify/notifyall functions similar to object. With this flexibility, multiple condition (object monitor) instances can be created within a lock object, and thread objects can be registered in the specified condition object, allowing for selective thread notification, multi-channel notification, and more flexibility on the dispatch thread.
Each lock can have arbitrary data Condition object, Condition is bound with lock , so there is lock Fairness Characteristics: If it is a fair lock, the thread is released from the condition.await in the FIFO order, and if it is a non-fair lock, then the subsequent lock contention does not guarantee the FIFO order.
Here is an example of a producer and a consumer:
/* * buyer thread, buy a book when there is a book in the bookstore */ public class Buyer extends Thread { private bookstore bookstore; public Buyer (Bookstore bookstore) {this . Bookstore = bookstore; @Override public void run () { while (true
/* * salesperson Thread, when there is a vacancy in the bookstore, buy books */ public class Seller extends Thread { private bookstore bookstore; public Seller (Bookstore bookstore) {this . Bookstore = bookstore; @Override public void run () { while (true
Importjava.util.ArrayList;Importjava.util.concurrent.locks.Condition;ImportJava.util.concurrent.locks.ReentrantLock;/** Bookstore Class*/ Public classBookstore {PrivateArrayList books =NewArrayList (); PrivateReentrantlock lock =NewReentrantlock (false); PrivateCondition buycondition =lock.newcondition (); PrivateCondition sellcondition =lock.newcondition (); Public voidAddbook () {lock.lock (); while(Books.size () >= 1) { Try{System.out.println (Thread.CurrentThread (). GetName ()+ "Waiting for books to be sold"); Sellcondition.await (); //The salesman waits for the bookstore to appear vacant}Catch(interruptedexception e) {e.printstacktrace (); }} books.add (1); Try{Thread.Sleep (1000); } Catch(interruptedexception e) {e.printstacktrace (); } System.out.println (Thread.CurrentThread (). GetName ()+ "purchased a book, Remaining:" +books.size ()); Buycondition.signal (); //notify buyers to buy booksLock.unlock (); } Public voidRemovebook () {lock.lock (); while(Books.size () <= 0) { Try{System.out.println (Thread.CurrentThread (). GetName ()+ "Waiting to buy books"); Buycondition.await (); //buyer waits for bookstore to enter book}Catch(interruptedexception e) {e.printstacktrace (); }} books.remove (0); Try{Thread.Sleep (1000); } Catch(interruptedexception e) {e.printstacktrace (); } System.out.println (Thread.CurrentThread (). GetName ()+ "bought a book, Remaining:" +books.size ()); Sellcondition.signal (); //inform the salesman to enter the bookLock.unlock (); }}
/** Test Class*/ Public classTest { Public Static voidMain (string[] args) {Bookstore Bookstore=NewBookstore (); Buyer[] Buyers=NewBuyer[5]; Seller sellers; //Create 5 Buyer threads, responsible for buying a book for(inti = 0; I < 5; i++) {Buyers[i]=NewBuyer (Bookstore); } //Create a salesperson thread, be responsible for entering the bookSellers =NewSeller (Bookstore); //Start ThreadSellers.start (); for(inti = 0; I < 5; i++) {Buyers[i].start (); } }}
Operation Result:
From the results we can see that the salesperson thread and the buyer thread are running alternately, because the two types of threads are bound to two different condition:buycondition,sellcondition. This enables alternating wake-up of two types of threads.
Using Reentrantlock and condition to implement inter-thread communication