多线程协作-生产者和消费者


public
class Product{ private String name; public Product(String name){ this.name = name; } //重写了Product类的toString方法,自定义Product类的Feild展示为字符串的格式 public String toString(){ return "Product-"+this.name; } }
import java.lang.Thread;

//采用默认的default访问控制符,仅限当前类的同一个包中类访问
class Producter extends Thread{
    //生产者生产产品,需要放入仓库,还需要区分生产的产品
    private WareHouse wareHouse ;
    private static int productName ;
    //线程是否运行标记
    private boolean running = false;
    
    public Producter(WareHouse wareHouse, String producterNmae){
        //继承Thread的构造函数,也就继承了Thread对象的功能
        super(producterNmae);
        this.wareHouse = wareHouse;
        }
    
    public void start(){
        this.running = true;
        super.start();
        }
        
    public void run(){
        Product product;
        try{
            while(this.running){
            //(int类型的productName)+(""),合并的结果为String类型
            product = new Product((++productName)+"");
            this.wareHouse.storageProduct(product);
            //等待wait状态的线程执行完synchronized代码块,当前线程再释放对象锁
            //主要是为了暂停当前线程,把cpu片段让出给其他线程,减缓当前线程的执行
            Thread.sleep(10);
            }
        }catch(InterruptedException e){
            e.printStackTrace();
            }
        }
    
    //将当前生产者线程停止
    public void stopProduct(){
        //线程同步的资源对象是仓库
        synchronized (wareHouse){
            this.running = false;
            System.out.println("Producter["+Thread.currentThread().getName()+"]停止了!");
            //将所有等待WareHouse对象的线程唤醒,告知当前线程停止
            this.wareHouse.notifyAll();
//            this.wareHouse.notify();
            }
        }
        
    public boolean isRunning(){
        return this.running;
        }    
    }
import java.lang.Thread;

//采用默认的default访问控制符,仅限当前类的同一个包中类访问
class Customer extends Thread{
    private WareHouse wareHouse;
    private boolean running = false ;
    
    public Customer(WareHouse wareHouse, String customerName){
        super(customerName);
        this.wareHouse = wareHouse ;
        }
        
    public void start(){
        this.running = true ;
        super.start();
        }
        
    public void run(){
        try{
            while(this.running){
            this.wareHouse.getProduct();
            Thread.sleep(1000);
            }
        }catch(InterruptedException e){
            e.printStackTrace();
            }
        }
        
    public void stopCustomer(){
        synchronized(this.wareHouse){
            this.running = false ;
            System.out.println("Customer["+Thread.currentThread().getName()+"]停止了!");
            //将所有等待WareHouse对象的线程唤醒,告知当前线程停止
            this.wareHouse.notifyAll();
//            this.wareHouse.notify();
            }
        }
        
    public boolean isRunning(){
        return this.running;
        }
    }
import java.lang.Thread;


//采用默认的default访问控制符,仅限当前类的同一个包中类访问
class WareHouse{
    //默认仓库容量
    private static int CAPACITY = 11 ;
    //存放产品的循环数组,生产的新产品紧跟现有产品后存放,消费的产品从现有产品首个开始获取
    private Product[] products;
    
    private int front = 0 ;        //仓库中第一个未消费产品下标
    private int rear = 0 ;        //仓库中最后一个未消费产品下标
    
    public WareHouse(){
        this.products = new Product[CAPACITY];
        }
        
    public WareHouse(int capacity){
        //初始还是默认仓库容量
        this();
        if(capacity > 0){
            CAPACITY = capacity + 1 ;
            this.products = new Product[CAPACITY];
            }
        }
        
    public void storageProduct(Product product){
        synchronized(this){
            boolean producerRunning = true ;
            Thread currentThread = Thread.currentThread();
            if(currentThread instanceof Producter){
                producerRunning = ((Producter)currentThread).isRunning();
            }else{return;}
                
            //保留最后一个可以存储的位置并等待销售唤醒,唤醒后如果还需要生产,但仅剩最后一个可以存储的位置则循环等待
            while(((rear+1) % CAPACITY) == front && producerRunning){
                System.out.println("Producter["+currentThread.getName()+"]满仓了!");
                try{
                    this.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                    }
                //唤醒后该生产者是否还需要生产
                producerRunning = ((Producter)currentThread).isRunning();
                System.out.println("Producter["+Thread.currentThread().getName()+"]"+ (producerRunning==true ? "正在运行":"停止了"));
                }
            //该生产者不需要生产,则结束
            if(!producerRunning){return;}
            this.products[rear] = product ;
            System.out.println("Producter["+currentThread.getName()+"] storageProduct :"+product.toString());
            //下一待存储下标循环下移
            rear = (rear + 1) %  CAPACITY;
            System.out.println("仓库中剩余未销售的产品数量:"+(rear+CAPACITY-front) % CAPACITY);
            //随机唤醒等待仓库资源对象的一个线程,包括生产者线程和消费者线程
            this.notify();
            }
        }
        
    public Product getProduct(){
        synchronized(this){
            boolean customerRunning = false ;
            Thread customerThread = Thread.currentThread();
            if(customerThread instanceof Customer){
                customerRunning = ((Customer)customerThread).isRunning();
            }else{return null;}
            while(front==rear && customerRunning){
                System.out.println("Customer["+customerThread.getName()+"]仓库空了!");
                try{
                    this.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                    }
                customerRunning = ((Customer)customerThread).isRunning();
                System.out.println("Customer["+Thread.currentThread().getName()+"]"+ (customerRunning==true ? "正在运行":"停止了"));
                }
            if(!customerRunning){return null;}
            Product product = this.products[front];
            System.out.println("Customer["+customerThread.getName()+"] getProduct : "+product.toString());
            //下移待销售下标循环下移
            front = (front + 1 + CAPACITY) % CAPACITY;
            System.out.println("仓库中剩余未销售的产品数量:"+(rear+CAPACITY-front) % CAPACITY);
            //随机唤醒等待仓库资源对象的一个线程,包括生产者线程和消费者线程
            this.notify();
            return product;
            }
        }    
    }
import java.lang.Thread;

public class ProductTest{
    public static void main(String[] args){
        WareHouse wareHouse = new WareHouse(2);
        Producter producter1 = new Producter(wareHouse, "producter-1");
        Producter producter2 = new Producter(wareHouse, "producter-2");
        Producter producter3 = new Producter(wareHouse, "producter-3");
        Customer customer1 = new Customer(wareHouse, "customer-1");
        Customer customer2 = new Customer(wareHouse, "customer-2");
        Customer customer3 = new Customer(wareHouse, "customer-3");
        Customer customer4 = new Customer(wareHouse, "customer-4");
//        producter1.start();
//        producter2.start();
//        producter3.start();
//        customer1.start();
//        customer2.start();
//        customer3.start();
//        customer4.start();
        
        producter1.start();
        customer1.start();
        
        producter2.start();
//        customer2.start();
        
        producter3.start();
//        customer3.start();
//        customer4.start();
        try{
            Thread.sleep(1600);
        }catch(InterruptedException e){
            e.printStackTrace();
            }
//        producter1.stopProduct();
//        producter2.stopProduct();
//        producter3.stopProduct();
//        customer1.stopCustomer();
//        customer2.stopCustomer();
//        customer3.stopCustomer();
//        customer4.stopCustomer();
        
        producter1.stopProduct();
        customer1.stopCustomer();
        
        producter2.stopProduct();
//        customer2.stopCustomer();
        
        producter3.stopProduct();
//        customer3.stopCustomer();
//        customer4.stopCustomer();
        }
    }

运行结果:

 

posted @ 2018-08-26 18:34  celineluo  阅读(198)  评论(0编辑  收藏  举报