Producer / consumer model (five)

Foreword

In the understanding of multi-threaded (a), we held over an example about synchronization application. He said that producers and consumers. We know that there is a communication between threads and threads. In this blog, will detail what is the producer / consumer model.

What is a producer / consumer model

An important model, based on waiting / notification mechanism. Producer / consumer model is described as a buffer warehouse, producers can product into the warehouse, consumers can remove the product from the warehouse, the producer / consumer model is concerned that the following points:

  • Producers to produce when consumers can not consume
  • Consumer spending when the producer can not produce
  • Buffer empty when consumers can not consume
  • When the buffer is full, the producer can not produce

Manufacturer / Model as an important model, it is advantageous in that:

  • Decoupling. Because more than a buffer, so producers and consumers do not directly call each other, it is very easy to think, so that producers and consumers of the code changes will not affect the other, so in fact put producers strong coupling between the consumer and solved, becomes a weak coupling between the producer and buffer / consumer buffers and
  • To improve the overall speed of processing data by balancing both producers and consumers of processing power , which is the most important producer / consumer model an advantage. If consumers take data directly from the producers here, if the producer of the production is slow, but consumer spending is fast, and that consumers have to take up CPU time slice waited in vain over there. With producer / consumer model, the producer and the consumer is complicated by two separate bodies, the producer of the produced data to the buffer like a lost, do we need consumers; consumers also, from the buffer get data just fine, do not have to pipe producers, not production buffer is full, the buffer is not empty the consumer, the producer / consumer of the processing capacity of a dynamic balance

 

Use wait () / notify () to achieve the producer / consumer model

Since the producer / consumer model has a buffer, then we do ourselves a buffer, producers and consumers of communication is through the buffer. value to "" indicates that the buffer space, value is not "" indicates that the buffer is full:

public class ValueObject
{
    public static String value = "";
}

The next step is a producer, if the buffer is full, then wait (), is no longer produced, consumers wait for complete consumer notice; if the buffer is empty, then the production data into the buffer

Copy the code
public class Producer
{
    private Object lock;
    
    public Producer(Object lock)
    {
        this.lock = lock;
    }
    
    public void setValue()
    {
        try
        {
            synchronized (lock)
            {
                if (!ValueObject.value.equals(""))
                    lock.wait();
                String value = System.currentTimeMillis() + "_" + System.nanoTime();
                System.out.println("Set的值是:" + value);
                ValueObject.value = value;
                lock.notify();
            }
        }
        catch (InterruptedException e)
        { 
            E.printStackTrace (); 
        } 
    } 
}
Copy the code

Similarly consumer, if the buffer is empty, then there is no consumption, wait () Wait, wait producers of finished production of the notice; if the buffer is not empty, then get the data:

Copy the code
public class Customer
{
    private Object lock;
    
    public Customer(Object lock)
    {
        this.lock = lock;
    }
    
    public void getValue()
    {
        try
        {
            synchronized (lock)
            {
                if (ValueObject.value.equals(""))
                    lock.wait();
                System.out.println("Get的值是:" + ValueObject.value);
                ValueObject.value = "";
                lock.notify();
            }
        } 
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
Copy the code

Write a main function, to open two threads call Producer inside getValue () method and the Customer () inside the setValue () method:

Copy the code
public static void main(String[] args)
{
    Object lock = new Object();
    final Producer producer = new Producer(lock);
    final Customer customer = new Customer(lock);
    Runnable producerRunnable = new Runnable()
    {
        public void run()
        {
            while (true)
            {
                producer.setValue();
            }
        }
    };
    Runnable customerRunnable = new Runnable()
    {
        public void run()
        {
            while (true)
            {
                customer.getValue();
            }
        }
    };
    Thread producerThread = new Thread(producerRunnable);
    Thread CustomerThread = new Thread(customerRunnable);
    producerThread.start();
    CustomerThread.start();
}
Copy the code

Look at the results:

Copy the code
... 
value Set are: 1444025677743_162366875965845 
value Get that: 1444025677743_162366875965845 
value Set are: 1444025677743_162366875983541 
value Get that: 1444025677743_162366875983541 
Set values are: 1444025677743_162366876004776 
Get values are: 1444025677743_162366876004776 
...
Copy the code

Production data and consumption data must be in pairs, a production of a consumer, not full production, not consumption empty, producers can not produce unlimited, consumers can not be unlimited consumption, in line with the producer / consumer model. Producers speed, not CPU time slice, waiting for consumers to continue to produce finished consumer notice it, this piece can be used to time with other threads.

 

Using the await () / signal () to achieve producer and consumer model

Like, first define a buffer zone:

public class ValueObject
{
    public static String value = "";
}

In other kinds of writing, production and consumption methods in a single class:

Copy the code
public class ThreadDomain41 extends ReentrantLock
{
    private Condition condition = newCondition();
    
    public void set()
    {
        try
        {
            lock();
            while (!"".equals(ValueObject.value))
                condition.await();
            ValueObject.value = "123";
            System.out.println(Thread.currentThread().getName() + "生产了value, value的当前值是" + ValueObject.value);
            condition.signal();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        finally
        {
            unlock();
        }
    }
    
    public void get()
    {
        try
        {
            lock();
            while ("".equals(ValueObject.value))
                condition.await();
            ValueObject.value = "";
            System.out.println(Thread.currentThread().getName() + "消费了value, value的当前值是" + ValueObject.value);
            condition.signal();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        finally
        {
            unlock();
        }
    }
}
Copy the code

Similarly, two open thread, a thread calls set () method of production, another thread calls the get () method consumption:

Copy the code
public static void main(String[] args)
{
    final ThreadDomain41 td = new ThreadDomain41();
    Runnable producerRunnable = new Runnable()
    {
        public void run()
        {
            for (int i = 0; i < Integer.MAX_VALUE; i++)
                td.set();
        }
    };
    Runnable customerRunnable = new Runnable()
    {
        public void run()
        {
            for (int i = 0; i < Integer.MAX_VALUE; i++)
                td.get();
        }
    };
    Thread ProducerThread = new Thread(producerRunnable);
    ProducerThread.setName("Producer");
    Thread ConsumerThread = new Thread(customerRunnable);
    ConsumerThread.setName("Consumer");
    ProducerThread.start();
    ConsumerThread.start();
}
Copy the code

Look at the results:

Copy the code
... 
Producer production value, the current value is the value of 123 
Consumer consumption of value, the current value is the value of the 
Producer production value, the current value is the value of 123 
Consumer consumption of value, the current value is the value of the 
Producer production value, value is the current value of 123 
consumer consumption of value, value of the current value is 
...
Copy the code

And wait () / notify () mechanism to achieve the same effect, in line with the same producer / consumer model

 

Be careful suspended animation

The purpose producer / consumer model eventually reach a balance of processing power producers and consumers , to achieve this process, does not require only a producer and a consumer. Producers may correspond to a plurality of the plurality of consumers, a consumer may correspond to a producer, the producer may correspond to a plurality of consumers.

Suspended animation took place under the above three scenarios. Theoretical analysis will be able to explain the problem, so do not write code. Write the code is very simple, just two examples of a modified, open a thread producer / consumer multiple threads to open multiple threads producer / consumer threads, threads to open multiple producers / consumers more thread can be. Suspended animation means that all the threads into the WAITING state, the program will no longer perform any business functions, and the entire project presents a standstill.

Let's say there is A producer and producer B, because the buffer is empty, the consumer is in WAITING. Producer B in WAITING, producer A production is notified consumers, producers A product produced should inform consumers, the results inform the producer B, B producers is awakened, discovered buffer is full, then continue WAITING . So far, two producers thread is WAITING, consumers are WAITING, the system suspended animation.

The above analysis we can see, the reason is because of the emergence of suspended animation notify of its kind, the non-single producer / single consumer scenarios can be taken two ways to solve this problem:

Wake up all the threads 1, synchronized with notifyAll () wakes up all the threads, ReentrantLock with signalAll ()

2, with two defined ReentrantLock Condition, Condition represent a producer, a consumer representation Condition, wake-up call when the corresponding Condition of signal () method on it

 

See link: https: //www.cnblogs.com/xrq730/p/4855663.html

Guess you like

Origin www.cnblogs.com/vole/p/12593284.html