生産消費者モデル


マルチスレッドの典型的な応用は生産消費者モデルであり、このモデルは実際にはマルチスレッドの通信であり、notify/waitメカニズムを使用している.このモデルの利点は、生産者がバッファにデータを書き、消費者がバッファデータを使用することで、論理が明確になり、また、速く遅くなることを避けることができるバッファがあることです.このモードは1/1,1/N,N/N,N/1のモードに分かれている.その原理はすべて同じで、ここで1/1の例を書きます.
ここでcacheオブジェクトはバッファとして、lockはロックオブジェクトとして機能します.生産消費者はバッファにデータを読み書きし続けている.以下のコードをよく分析すると、1/1の生産消費が比較的簡明であることがわかります.
生産者スレッドを参照:
package com.lenovo.plm.dms.p12;

import java.util.Map;

public class MyThreadA extends Thread{
    
    Map<String,String> cache;
    Object lock;
    
    public MyThreadA(Map<String,String> cache,Object lock){
        this.cache = cache;
        this.lock = lock;
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run(); 
        while(true){
            synchronized(lock){
                if(cache.size() != 0){
                    System.out.println(Thread.currentThread().getName() + " begin to wait.");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " end to wait.");
                }
                long time = System.nanoTime();
                System.out.println("the value for producer is: " + time);
                cache.put("time",String.valueOf(time));
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                lock.notify();
            }
        }
        
    }
}

消費者スレッドを見てみましょう.
package com.lenovo.plm.dms.p12;

import java.util.Map;

public class MyThreadB extends Thread{

    Map<String,String> cache;
    Object lock;
    
    public MyThreadB(Map<String,String> cache,Object lock){
        this.cache = cache;
        this.lock = lock;
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        while(true){
            synchronized(lock){
                if(cache.size() == 0){
                    System.out.println(Thread.currentThread().getName() + " begin to wait.");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " end to wait.");
                }
                System.out.println("The value for consumer is: " + cache.get("time"));
                cache.remove("time");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                lock.notify();
            }
        }
        
    }
}

最後の実行クラス:
package com.lenovo.plm.dms.p12;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        
        Object lock = new Object();
        Map<String,String> cache = new HashMap<String,String>();
        MyThreadA t1 = new MyThreadA(cache,lock);
        t1.setName("producer");
        t1.start();
        
        MyThreadB t2 = new MyThreadB(cache,lock);
        t2.setName("consumer");
        t2.start();
    }
}

最後の実行結果は次のとおりです.
the value for producer is: 5202433063937 The value for consumer is: 5202433063937 the value for producer is: 5208443181133 The value for consumer is: 5208443181133 consumer begin to wait. the value for producer is: 5214461465895 consumer end to wait. The value for consumer is: 5214461465895 the value for producer is: 5220470907482 producer begin to wait. The value for consumer is: 5220470907482