Multi-producer Multi-Consumer problem (lock interface, condition interface)

Source: Internet
Author: User

In the multi-producer multi-consumer problem, we solved the problem through the while judgment and the Notifyall () Full Wake method, but Notifyall () also brought the disadvantage that it wakes all the waiting threads, which means both awakening the other, and awakening the side, After the wake of the side of the thread to continue to judge the mark, it reduces the efficiency of the program. We want to wake only each other's threads.

A similar problem is resolved after the JDK has been upgraded.

The lock (interface) implementation provides a wider range of locking operations than is available with synchronized methods and statements.

Synchronized Sync code block format:

Object Obj=new object ();
void Show ()
{
	synchronized (obj)
	{	
		//code required to be synchronized
	}
}
Note: The code block is synchronized, and the operation of the lock is implicit.


jdk1.5 later encapsulates synchronization and locks into objects, and defines an implicit way of manipulating the lock into the object, which turns the implicit action into a display action.

Following the new JDK features to implement the lock interface custom lock implementation synchronization:

Lock lock=new Reentrantlock ();  The Reentrantlock class is a subclass of the lock class, which implements the lock interface
void Show ()
{
	try
	{
		lock.lock ();	Get lock
		//code
	}
	
	finally
	{
		lock.unlock ();	Release lock
	}
	
}


We rewrite the example of multiple producers and consumers (multiple producer and consumer issues):

Import java.util.concurrent.locks.*;
	Lock is a class in another package that needs to be imported//resource class Resource {private String name;
	private int count=1; Private Boolean flag=false;  Sets the flag bit value to False, indicating that the Lock lock=new Reentrantlock () was not produced;
		Implements an interface public void set (String name) {Lock.lock (); The try {while (flag)//while guarantees that the awakened thread at this point is to reconsider the flag bit try{this.wait ();} catch (Interruptedexception e) {} this.name
			=name+count;
			count++; System.out.println (Thread.CurrentThread (). GetName () + "...
			Producer ... "+this.name);
			Flag=true;  Notifyall ();		
		Guaranteed to wake consumer thread} finally {Lock.unlock ();
		} public synchronized void out () {lock.lock (); try {while (!flag) try{this.wait ();} catch (Interruptedexception e) {} System.out.println (Thread.CurrentThread (). GetName () + "...
			Consumers ... "+this.name);
			Flag=false;  Notifyall ();
		Guaranteed to wake Producer threads} finally {Lock.unlock ();
	}}//Producer class Producer implements Runnable {private Resource R;
	Producer (Resource R) {this.r=r;
	}public void Run () {while (true) {R.set ("roast duck");
	}}//Consumer class Consumer implements Runnable {private Resource R;
	Consumer (Resource R) {this.r=r;
		public void Run () {while (true) {r.out ();
		}} class Producerconsumerdemo {public static void main (string[] args) {Resource r=new Resource ();
		Producer pro=new Producer (R);

		Consumer con=new Consumer (R);
		2 producers, 2 consumers thread t0=new thread (PRO);
		Thread T1=new thread (PRO);
		Thread t2=new thread (con);

		Thread t3=new thread (con);
		T0.start ();
		T1.start ();
		T2.start ();
	T3.start (); }
}

Run Result:

But in the example above, the lock we used was lock, no longer this, and the lock on the Wait (), Notifyall () method in the code is still this, and an error occurs, and in the new JDK feature, lock is used instead of synchronized. Replace the Monitor method with condition (Wait (), notify (), Notifyall ()).

Condition Interface:

The interface Condition  //condition interface replaces the Wait (), notify (), Notifyall () method in the object class
{
	await ();
	Signal ();
	Signalall ();
}
 
Lock lock=new Reectrantlock ();    One lock creates two monitors, one lock has multiple monitor methods
Condition c1=lock.newcondition (),//await (), signal (), Signalall () method
in each monitor Condition c2=lock.newcondition ();


Or do you want to continue rewriting the previous example:

Import java.util.concurrent.locks.*;
	Lock is a class in another package that needs to be imported//resource class Resource {private String name;
	private int count=1; Private Boolean flag=false;  Sets the flag bit value to false, indicating that there is no production//Lock object Lock Lock=new Reentrantlock ();  Implements an interface//Gets the monitor object of the lock via an existing lock Condition con=lock.newcondition ();
		Con is a monitor on lock lock public void set (String name) {Lock.lock (); The try {while (flag)//while guarantees that the awakened thread at this point is to reconsider the flag bit//try{lock.wait ();} catch (Interruptedexception e) {} Try{con . await ();
			catch (Interruptedexception e) {} this.name=name+count;
			count++; System.out.println (Thread.CurrentThread (). GetName () + "...
			Producer ... "+this.name);
			Flag=true;  Notifyall ();
		Guaranteed to awaken consumer thread con.signalall ();		
		finally {Lock.unlock ();
		} public synchronized void out () {lock.lock (); try {while (!flag)//try{this.wait ();} catch (Interruptedexception e) {} try{con.await ();} catch (Interruptedexcep tion e) {} System.out.println (Thread.CurrentThread (). GetName () + "...Consumers ... "+this.name);
			Flag=false;  Notifyall ();
		Guaranteed to awaken producer thread Con.signalall ();
		finally {Lock.unlock ();
	}}//Producer class Producer implements Runnable {private Resource R;
	Producer (Resource R) {this.r=r;
		public void Run () {while (true) {R.set ("roast duck");
	}}//Consumer class Consumer implements Runnable {private Resource R;
	Consumer (Resource R) {this.r=r;
		public void Run () {while (true) {r.out ();
		}} class Producerconsumerdemo {public static void main (string[] args) {Resource r=new Resource ();
		Producer pro=new Producer (R);

		Consumer con=new Consumer (R);
		2 producers, 2 consumers thread t0=new thread (PRO);
		Thread T1=new thread (PRO);
		Thread t2=new thread (con);

		Thread t3=new thread (con);
		T0.start ();
		T1.start ();
		T2.start ();
	T3.start ();
 }
}
Run Result:



We mentioned earlier that we wanted to wake up the other thread to improve the efficiency of the program. If there is only one monitor in the program, it can wake up all the producer consumers and all the producers. Actually we want producers to awaken consumers, consumers awaken producers, so we create two sets of monitors, a group of monitoring producers, and a group of monitoring consumers.

Import java.util.concurrent.locks.*;
	Lock is a class in another package that needs to be imported//resource class Resource {private String name;
	private int count=1; Private Boolean flag=false;  Sets the flag bit value to false, indicating that there is no production//Lock object Lock Lock=new Reentrantlock ();  Implements an interface//Gets the monitor object of the lock via an existing lock//condition con=lock.newcondition ();    Con is a monitor on lock lock//Get two sets of monitors through existing locks, a group of monitoring producers, a group of monitoring consumer Condition producer_con=lock.newcondition ();    Producer's Monitor Condition consumer_con=lock.newcondition ();
		Consumer's monitor public void set (String name) {Lock.lock (); The try {while (flag)//while guarantees that the awakened thread at this point is to reconsider the flag bit//try{lock.wait ();} catch (Interruptedexception e) {} Try{pro Ducer_con.await ();}
			catch (Interruptedexception e) {}//producer thread waits for This.name=name+count;
			count++; System.out.println (Thread.CurrentThread (). GetName () + "...
			Producer ... "+this.name);
			Flag=true;  Notifyall ();
			Guaranteed to awaken consumer thread//con.signalall (); Consumer_con.signal ();		
		Wake up a consumer's thread} finally {Lock.unlock (); } synchronized void Out ()
	{Lock.lock (); try {while (!flag)//try{this.wait ();} catch (Interruptedexception e) {} try{consumer_con.await ();} catch (Interru Ptedexception e) {}//consumer thread waits for System.out.println (Thread.CurrentThread (). GetName () + "...
			Consumers ... "+this.name);
			Flag=false;  Notifyall ();
			Guaranteed to awaken producer thread//con.signalall (); Producer_con.signal ();
		Wake Producer of a thread} finally {Lock.unlock ();
	}}//Producer class Producer implements Runnable {private Resource R;
	Producer (Resource R) {this.r=r;
		public void Run () {while (true) {R.set ("roast duck");
	}}//Consumer class Consumer implements Runnable {private Resource R;
	Consumer (Resource R) {this.r=r;
		public void Run () {while (true) {r.out ();
		}} class Producerconsumerdemo {public static void main (string[] args) {Resource r=new Resource ();
		Producer pro=new Producer (R);

		Consumer con=new Consumer (R);
		2 producers, 2 consumers thread t0=new thread (PRO);
		Thread T1=new thread (PRO); Thread T2=new Thread (con);

		Thread t3=new thread (con);
		T0.start ();
		T1.start ();
		T2.start ();
	T3.start (); }
}
Run Result:


Summarize:

One: Lock interface: The replacement of the synchronization code block or synchronization function, the synchronization of the implicit lock operation into the actual lock operation, while more flexible, can be a lock plus multiple sets of monitors.

Method: Lock (): Get lock

Unlock (): Unlocking a lock, usually defined in a finally code block

Two: Condition interface: appear replaces the wait Notify Notifyall method in object, these monitor methods are encapsulated separately, become condition monitor object, can combine arbitrarily lock.

Method: Await ()

Signal ()

Signalall ()



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.