Java multithreading collaboration

The common way of thread collaboration is producer / consumer.

 

As a producer, a thread processes data. For example, take a thread to produce an Order. Every time a user makes a next Order, the thread produces an Order object.

Set up a warehouse to store the generated Order object.

A thread, as a consumer, consumes and processes the Order object (print Order, pick goods, delivery) in the warehouse.

 

 

 

 

 

demo order processing flow

 

1. Encapsulate the data to be processed with a class

public class Order {
    private int id;
    //...

    public Order(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    //......
}

 

 

2. Warehouse

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class OrderStorage {
    //Use blocking queue as warehouse
    private BlockingQueue<Order> queues;

    //Default warehouse capacity is 50
    public OrderStorage() {
        this.queues = new LinkedBlockingQueue<>(50);
    }

    //Initialize warehouse capacity
    public OrderStorage(int capacity) {
        this.queues = new LinkedBlockingQueue<>(capacity);
    }

    //Warehousing
    public void push(Order order) throws InterruptedException {
        queues.put(order);
    }

    //Out of stock
    public Order pop() throws InterruptedException {
        return queues.take();  //When there are no elements in the warehouse, the current thread will be blocked until there are elements to pop up. Or BlockingQueue
    }
}

There are many classes to be used concurrently under java.util.concurrent package, and the blocking queue we use is under this package. Concurrent

The queues are first in, first out. The ones produced by Mr. Chen are put in the warehouse and processed first.

 

 

3. Producers

public class ProducerThread extends Thread{
    public static OrderStorage orderStorage = new OrderStorage(100); //Warehouse capacity is 100

    @Override
    public void run() {
        int i=1;
        while (true){
            Order order = new Order(i);
            try {
                orderStorage.push(order); //Put it in the warehouse
                System.out.println("Produced No"+i+"Order");
                Thread.sleep(1000); //Reduce speed, easy to see effect
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i++;
        }
    }

}

The capacity is 100, which does not mean that only 50 orders can be generated. At the same time of production, consumers are also consuming orders in the warehouse.

 

 

4. Consumer

public class ConsumerThread extends Thread {
    private OrderStorage orderStorage=ProducerThread.orderStorage; //Consumers and producers use the same warehouse

    @Override
    public void run() {
        while (true){
            try {
                Order order = orderStorage.pop(); //If not in the warehouse Order,Will block the current thread until Order Can pop up
                System.out.println("Consumed|Process No"+order.getId()+"Order");
                Thread.sleep(1000); //Reduce speed, easy to see effect
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

 

 

5. Test class

public class Test {
    public static void main(String[] args) {
        ProducerThread producerThread = new ProducerThread();
        producerThread.start();

        ConsumerThread consumerThread = new ConsumerThread();
        consumerThread.start();

    }
}

 

 

6, effect

Sometimes an order prints "consumption" first, then "production".

The processing Order of an Order must be: production, receipt - > issue and consumption, which can only be obtained from the warehouse after being put into the warehouse.

It's just that the two threads of producer and consumer get the time slice in different order when they execute sout.

Tags: Java

Posted on Mon, 23 Mar 2020 09:12:10 -0700 by blackwidow