zoukankan      html  css  js  c++  java
  • 线程生产者与消费者

    package cn.itcast.thread;
    /*
     线程通讯:  一个A线程完成了当前的任务时,要通知另外B线程去做另外事情。
     
    生产者与消费者。


    问题一:价格错乱问题。(线程安全问题)


    问题: 目前要不就是生成一大批的产品,要不消费一大批的产品

    要求的效果: 生产一个消费一个。
     

     线程通讯相关方法:
         wait()       如果一个线程调用了wait方法,那么该线程会进入以锁对象的监听器作为标识符建立的线程池中等待。  等待状态先的线程会释放锁对象。
         notify()      如果一个线程调用了notify方法,那么会唤醒以锁对象的监听器建立的线程池中等待线程的其中一个。    
         notifyAll()  唤醒以锁对象的监听器建立线程池中 的所有等待线程。
     

    线程通讯要注意的事项:
        1. wait() ,notify() , notifyAll() 这三个方法都是属于Object类的,并不是属于Thread类的。
        2. 调用wait() ,notify() , notifyAll() 这三个方法都必须要在同步函数或者是同步代码块中调用,否则报错。
        3. 调用wait() ,notify() , notifyAll() 这三个方法都必须要由锁对象调用。
        
     */

    //产品类
    class Product{
        
        String name;
        
        int price;
        
        boolean  flag = false;     //是否生产完毕的标识     false为没有生产完成  ,true 生产完毕。
    }

    //生产者
    class  Producer extends Thread{
        
        Product p;
        
        public Producer(Product p){
            this.p = p;
        }
        
        
        @Override
        public void run() {
            int i = 0;
            while(true){
                synchronized (p) {
                    if(p.flag==false){
                        if(i%2==0){
                            p.name = "自行车";
                            p.price = 300;
                        }else{
                            p.name = "摩托车";   //摩托车  300
                            p.price = 4000;
                        }
                        System.out.println("生产者生成了"+p.name+" 价格是:"+ p.price);
                        //产品已经生成完毕,就应该唤醒消费者去消费。
                        p.flag   =true;
                        i++;
                        p.notify();
                    }else{
                        try {
                            p.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        
                    }
                }
                
            }
        }
    }


    //消费者
    class Customer extends Thread{
        
        Product p;
        
        public Customer(Product p) {
            this.p = p;
        }
        
        @Override
        public void run() {
            while(true){
                synchronized (p) {    
                    if(p.flag==true){
                        System.out.println("消费者消费了:"+ p.name+" 价格:"+ p.price);
                        p.flag = false;
                        p.notify();
                    }else{
                        try {
                            p.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        
    }

    public class Demo3 {
        
        public static void main(String[] args) {
            //创建一个产品对象
            Product p = new Product();
            //创建一个生产者对象
            Producer producer = new Producer(p);
            //创建消费者对象
            Customer customer = new Customer(p);
            //启动线程
            producer.start();
            customer.start();
            
            
        }

    }

  • 相关阅读:
    android之PackageManager简单介绍
    OUI-67076 : OracleHomeInventory was not able to create a lock file" in Unix
    编程之美2013 初赛一 A
    Unity3D之挥动武器产生的剑痕特效
    怎样在万网加入Lync Online SRV记录
    mysql-定时调用存储过程
    在TextView中加入图片
    shell语法简单介绍
    quick-cocos2d-x android返回键监听并实现原生退出对话框
    秒杀多线程第四篇 一个经典的多线程同步问题
  • 原文地址:https://www.cnblogs.com/votg/p/5035543.html
Copyright © 2011-2022 走看看