Produktions- und Verbrauchsmodell – lassen Sie den Thread-Status nachvollziehen

Angenommen, Sie werden jetzt Chef von Jingdong, stoßen Sie auf ein Problem: Bei begrenzter Lagerkapazität die Warenlagerung kontrollieren und gleichzeitig versenden. Wie kann man diese Situation kontrollieren? In Java können wir das Produktionsverbrauchsmodell verwenden, um es abzuschließen.

Das Problem lässt sich wie folgt vereinfachen: Der Produzent stellt die Ware her und lagert sie ein, der Konsument entnimmt die Ware aus dem Lager

 

Aber wir werden auch auf einige Probleme stoßen: Die Effizienz ist zu gering, die Beurteilung des Lagers voll und leer

Lösungsidee : Verwenden Sie Parallelität , um die Effizienz zu verbessern, und verwenden Sie den Thread-Status , um das Lager voll und leer abzugleichen.

Jetzt beginnt offiziell:

1. Erstellen Sie eine Lagerklasse, und die Mitgliedsdaten sind die Warenmenge.

2. Erstellen Sie einen Produzenten-Thread:

Es lohnt sich, nach den verschiedenen Zuständen des Threads zu suchen!

/**
                 * Der Thread wartet auf Wait, das heißt, der Thread hat kein Recht zu arbeiten und wird nicht ausgeführt, unabhängig davon, ob der CPU Zeit zugeteilt wird.* Der Thread
                 wacht auf, benachrichtigt, was bedeutet, dass der Thread aufwacht auf und erhält das Recht zu arbeiten. Es kann laufen, solange die CPU-Zeit erhalten ist.
                 * Verwenden Sie warten, benachrichtigen Obtain the object monitor before, andernfalls wird eine IllegalMonitorStateException
                 geworfen obj), damit andere Threads obj.notify() ausführen können.
                 * Notify() wird die obj-Sperre in sycronized (obj) jedoch nicht sofort freigeben, es muss warten, bis der Thread, in dem sich Notify() befindet, den gesamten Code im synchronisierten (obj) Block ausführt, bevor er die Sperre freigibt.
                 * Der Grund, warum die Verwendung von lock auch die Sperre aufheben kann, weil ReentrantLock basierend auf synchronisiert geschrieben wird
                 */

public class Producer implements Runnable{
    //得到唯一仓库对象,方便上锁以及wait方法
    private Store store;
    public Producer(Store store){
        this.store = store;
    }
    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            /**
             * 由于并发式操作,为了保证线程安全,需要使用“锁”
             * 但是,必须保证锁和wait作用于同一对象,不然会出现“死锁”现象
             */
            synchronized (store) {
                /**
                 * 线程等待wait,即线程没有操作权,无论cpu有无分配到时间都不会执行
                 * 线程唤醒notify,即将线程唤醒,获取操作权,只要得到cpu时间就可运行
                 * 使用wait,notify之前要获取对象监视器,不然会抛出IllegalMonitorStateException异常
                 * wait()会立刻释放synchronized(obj)中的obj锁,以便其他线程可以执行obj.notify()。
                 * 但是notify()不会立刻立刻释放sycronized(obj)中的obj锁,必须要等notify()所在线程执行完synchronized(obj)块中的所有代码才会释放这把锁。
                 * 之所以用lock也可以释放锁,因为ReentrantLock是基于synchronized而所写的
                 */
                if (store.N >= 20){
                    try {
                        //得知仓库已满状态
                        System.out.println("仓库已满"+Thread.currentThread().getName()+"生产者进入等待状态");
                        store.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else {
                    //如果没有满,则开始生产
                    store.N++;
                    System.out.println(Thread.currentThread().getName() + "线程 正在生产数据...   " + store.N);
                    /**
                     * 开始唤醒生产者,进行生产,给消费者提供数据消费
                     * 同时保证了,生产消费可以一直进行下去。
                     */
                    store.notify();
                }
            }
        }
    }
}

3. Erstellen Sie einen Consumer-Thread:

Die Idee stimmt mit dem Produzenten-Thread überein.

4. Starten Sie den Thread im Lager:

 public void start(){
        Producer producer= new Producer(this);
        new Thread(producer).start();
        new Thread(producer).start();
        new Thread(producer).start();

        Consumer consumer = new Consumer(this);
        new Thread(consumer).start();
        new Thread(consumer).start();

    }
    public static void main(String[] args) {
        Store ss = new Store();
        ss.start();
    }

Operationsergebnis:

 

Je suppose que tu aimes

Origine blog.csdn.net/AkinanCZ/article/details/126917750
conseillé
Classement