• 线程生产者与消费者


    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();
            
            
        }

    }

  • 相关阅读:
    基于三角形问题通过边界值分析和等价类划分进行黑盒测试
    小程序学习记录【数组操作相关(持续更新)】(1)
    Android实现九宫拼图过程记录
    高维数据Lasso思路
    CannyLab/tsne-cuda with cuda-10.0
    xgboost 多gpu支持 编译
    GDAL2.2.4 C#中的编译及使用
    SqlServer性能优化,查看CPU、内存占用大的会话及SQL语句
    WinForm任务栏最小化
    datatable与实体类之间相互转化的几种方法
  • 原文地址:https://www.cnblogs.com/votg/p/5035543.html
Copyright © 2020-2023  润新知