• 多线程案例:生产者和消费者


    1.生产和消费的产品抽象类:
    public abstract class Product {
        public String name;
        public abstract String toString();
    }

    2.一个具体的产品类:

    public class AProduct extends Product {
        public AProduct(String name) {
            this.name = name;
            // TODO Auto-generated constructor stub
        }
        public String toString() {
            // TODO Auto-generated method stub
            return this.name;
        }
    }

    3.容器类(仓库):

    import java.util.ArrayList;

    /*
     * 存放生产者和消费者的产品队列
     * */

    public class Container {
        private ArrayList arrList = new ArrayList();
        private int LENGTH = 10;
        public boolean isFull() {
            return arrList.size()==LENGTH;
        }
        public boolean isEmpty() {
            return arrList.isEmpty();
        }

        /* 如果此处不加synchronized锁,那么也可以再调用push的地方加锁
        * 既然此处加了锁,那么再别的地方可以不加锁
        */

        public synchronized void push(Object o) {
            arrList.add(o);
        }
        // 如果此处不加synchronized锁,那么也可以再调用push的地方加锁
        public synchronized Object pop() {
            Object lastOne = arrList.get(arrList.size()- 1);
            arrList.remove(arrList.size()- 1);
            return lastOne;
        }
    }

    4.休息一会,生产者和消费者都要休息,因此作为抽象基类:

    public abstract class Sleep {
        public void haveASleep() throws InterruptedException {
            Thread.sleep((long)(Math.random()* 3000));
        }
    }

    /*
     * 消费者线程
     * */

    public class Consumer extends Sleep implements Runnable {
        private Container contain =null;
        public Consumer(Container contain) {
            this.contain = contain;
        }
        public void run() {
            // TODO Auto-generated method stub
            while(true) {
                synchronized(contain) {
                    while(contain.isEmpty()) {
                        try{
                            contain.wait();
                        }catch(InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
                consume();//消费
                try {
                    haveASleep();
                }catch(InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized(contain) {
                    contain.notify();
                }
            }
        }
        private void consume() {
            Product a = (AProduct)contain.pop();
            System.out.println("消费了一个产品"+ a.toString());
        }
    }

    /*
     * 生产者线程
     * */

    public class Producator extends Sleep implements Runnable {
        private Container contain = null;
        public Producator(Container contain) {
            super();
            this.contain = contain;
        }
        public void run() {
            // TODO Auto-generated method stub
            while(true) {
                synchronized(contain) {
                    while(contain.isFull()) {
                        try{
                            contain.wait();// 阻塞当前线程,当前线程进入等待队列。这个时候只有等待别的线程来唤醒自己了。
                        }catch(InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
                producer();// 生产一个产品
                try {
                    haveASleep();
                }catch(InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized(contain) {
                    contain.notify();// 唤醒等待队列中正在等待的第一个线程,让其执行。
                }
            }
        }
        public void producer() {
            Product aProduct = new AProduct("pp:"+String.valueOf((int)(10*Math.random())));
            System.out.println("生产了一个产品:"+ aProduct.toString());
            contain.push(aProduct);
        }
    }

    5. 写一个测试:

    public class TestMain {
        /**
         * @param args
         */

        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Container contain = new Container();
            Producator p = new Producator(contain);
            Consumer c = new Consumer(contain);
            Thread pt =new Thread(p);
            Thread ct =new Thread(c);
            pt.start();
            ct.start();
        }
    }

  • 相关阅读:
    echarts 图表缩放 X轴Y轴数据缩放
    avue大屏 avuedata echarts图形数据过多自动滚动
    地图自定义弹窗 高德地图信息窗体 鼠标点击地图点标记显示弹窗html
    地图自定义弹窗 高德地图信息窗体 鼠标点击地图点标记显示弹窗vue
    自动刷新页面的实现方法总结
    vs2008 切换到试图代码后自动关闭问题
    时间差值
    Array.prototype.slice() 方法
    Array.prototype.slice.call()详解及转换数组的方法
    [UNIX网络编程1.0]源代码在linux系统下的实现
  • 原文地址:https://www.cnblogs.com/smallfa/p/1109565.html
Copyright © 2020-2023  润新知