Java Producer Consumer Model

Source: Internet
Author: User

Introduction:

The producer-consumer model of the operating system curriculum can be said to be the best example of learning concurrency. It is important to note that Java does not support processes and only supports multithreading. This article will explain Java concurrency in one of the simplest producer consumer models. Learning this blog post you should have learned a few things

1. How multiple threads Read and write a variable correctly and concurrently

2. Implementation of producer consumer models

Java Concurrency:

As noted above, there are no processes in Java that are only threads, so Java concurrency involves only threads. In Java there are two ways to create a thread, the first is to inherit the thread class, and the second is to implement the Runnable interface. Two methods of personal preference for the second, because there is no more inheritance in Java, so if the first kind of inheriting the thread class, then you can not inherit the other classes. Of course, if a class does not need to inherit other classes just a thread task class then inheriting thread is okay. In general, there is no difference.

Producer Consumer Model

The producer consumer model is applied everywhere in the project. This is a widely used and very simple model. There is usually a "producer" that produces data or adds consumption of data by one or more consumers. For example, we want to make a decoration order push demand. The producer of this scene is the production system of the order, each order we make an order into a set, and create several to the merchant push the thread task, these tasks listen to the order collection, found that there is an order to take out (this is the consumer behavior) and then match the merchant to push. The benefits of doing so

1. When an order is generated faster than the speed at which an order is pushed to the merchant (when data growth is inevitable), the benefits of pushing with multiple order push tasks are self-evident. If you just come up with an order and push it, it's obviously not keeping up with the speed of the order.

2. Loose coupling. Loose coupling is almost the ultimate goal of all methods, models, and frameworks. The use of producer consumers can make the modification of the order system and recommendation system does not interfere. No reaching.

See below for a small example.

public classThreadTest {//But understood as order quantity public static int count = 0; public static voidMain (string[] Argvs) {Producer Producer = newProducer (); Consumer Consumer1 = newConsumer (); Inherit thread create thread through Start method to start threadsProducer.start (); Implementing the Runnable interface creation thread to start a thread through the Run methodConsumer1.run (); System.out.println (count); }//producer produces an order public static void Countinc () {count++ ;}//consumer processes an order public static void  Countdec () {count--;}} Class Producer extends  thread {//This thread uses the inherited thread to implement the need to override the Run method. The producer produces an order without 20MS.  @Override public void  Run () {for (int i = 0; i < i++ ) {//TODO auto-generated Method stub  Threadtest.countinc (); try  {sleep ();} catch  (Interruptedexception e) {//TODO Au To-generated Catch block  e.printstacktrace ();}} }}class Consumer implements  Runnable {@Override//This thread implements Runnable interface, need to rewrite the Run method, this consumer does not consume an order public void 20MS  Run () {//TODO auto-generated method stub for (int i = 0; i < 10;i++ ) {threadtest.countdec (); try  { Thread.Sleep (),} catch  (Interruptedexception e) {//TODO auto-generated catch block  E.printstacktra CE (); } } } } 

Synchronized implementing Java Concurrency protection

This implementation is particularly straightforward. Just add a synchronized keyword to the function countinc and Countdec. Modify the following

public class ThreadTest {    //But understood as order quantity public    static int count = 0;    public static void Main (string[] Argvs) {        Producer Producer = new Producer ();        Consumer consumer1 = new Consumer ();         Inherit thread creation thread through the Start method to start Threads Producer.start ();//implement Runnable interface creation thread to start thread Consumer1.run () through the Run method; System.out.println (count); }//producer produces an order public static synchronized void Countinc () {count++;
Save some thing to MySQL}//consumer processes an order public static synchronized void Countdec () {count--;
Save some thing to MySQL}}

The rest of the code does not change. This time the operation is 0 each time, realizing the thread security purpose of multithreading to count access. Keyword synchronized although easy to use but the lock is locked to an object, the size of the lock is relatively large, so the efficiency is very low. For example, function countinc if it's not just for count+1, like doing some database operations, Then the keyword synchronized will cause the call to Countinc when the entire threadtest all other methods with the keyword synchronized can not be called, because it is locked. This is inefficient, because our goal is simply to lock up the count++ line of code. So a variety of locks are available in Java.

Lock implements Java concurrency

The code modified after using lock is as follows

public class ThreadTest {    //But understood as order quantity public    static int count = 0;    public static Lock lock = new Reentrantlock ();    public static void Main (string[] Argvs) {        Producer Producer = new Producer ();        Consumer consumer1 = new Consumer ();//Inherit thread create thread to start threads through the Start Method Producer.start (); Implement the Runnable interface creation thread by using the Run method to start thread consumer1.run (); System.out.println (count); }//producer produces an order public static void Countinc () {lock.lock (); count++; Lock.unlock ();//Some other code that does not require a lock }//Consumer division Reason an order public static void Countdec () {lock.lock (); count--; Lock.unlock ();//Some other code that does not require a lock }}
                

You can see here new a reentrantlock,java There are many other types of locks, and later have the opportunity to elaborate here for the time being not mentioned. You can see that the two lines of code for count++ and count--want to be locked before they run, so that the execution of the two lines of code is coprime and who gets the lock who can execute it. It is important to remember that calling the lock () function must call the unlock () function in the corresponding place, otherwise it will be wasted, and the whole system will die because of this little lock. Of course, you may also feel that this is more troublesome, there is no atomic shaping, the shape of the atom is thread-safe does not need to protect. The answer is yes.

Atomicinteger

The code is modified as follows

public class ThreadTest {    //is understood as order quantity public    static Atomicinteger count = new Atomicinteger (0);p ublic static void Main (string[] Argvs) {        Producer Producer = new Producer ();        Consumer consumer1 = new Consumer ();         Inherit thread creation thread through the Start method to start Threads Producer.start ();//implement Runnable interface creation thread to start thread Consumer1.run () through the Run method; System.out.println (count); }//producer produces an order public static void Countinc () {
Count plus 1 count.incrementandget (); Some other code that does not require a lock}//consumer processing an order public static void Countdec () {
Count minus 1 count.decrementandget (); Some other code that does not require a lock }}

The difference between Atomicinteger and int is like the difference between Hashtable and HashMap, one is thread-safe and one is thread insecure. Atomicinteger is a Java-enabled type of int that supports atomic operations, and so-called atomic operations are bound to be thread-safe during operation. In addition to Atomicinteger, there are atomic implementations of various data types under the Java.util.concurrent.atomic package.

OK, the content of this article is so much, this article many and miscellaneous, the design of the topic is relatively tall, need to absorb digestion carefully. In fact, this is just the tip of Java concurrency programming, but learning this small producer consumer model will certainly benefit you. Come on, young man.

Java Producer Consumer Model

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.