生产者消费者的一个面试问题

题目:写一个固定容量的同步容器,拥有put、get方法以及getCount方法,能够支持2个生产者以及10个消费者的阻塞调用。

思路
从题目可以得出这是一个同步容器,这就可以理解为该容器对象在调用过程中需要加锁,一般我们会想到synchornized,先用这个方法实现,下面是代码

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;

public class Container {
    final private LinkedList list=new LinkedList();
    final private int MAX=10;
    private int count=0;
    public synchronized void put(T t){
        /*这里必须使用while,首先wait和while经常一起使用,其次如果使用if,会出现错误数据。
        线程t一开始list.size()==MAX,线程t会wait,wait方法会释放锁.如果此时线程a执行get弄走一个数据,
        然后线程b执行put方法,发现list.size()
        while(list.size()==MAX){
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        count++;
        list.add(t);
        this.notifyAll();
    }
    public synchronized T get(){
        T t=null;
        while(list.size()==0){

            try {
                this.wait();  //wait()释放锁
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        t=list.removeFirst();
        count--;
        this.notifyAll();

        return t;
    }

    public int getCount(){
        return count;
    }
    public static void main(String[] args) {
        Container myCon=new Container();

        //10个消费者线程
        for (int i = 0; i < 10; i++) {

            Runnable c=new Runnable() {             
                @Override
                public void run() {
                    for (int j = 0; j < 5; j++) {
                        System.out.println(myCon.get());
                    }

                }
            };

            new Thread(c,"c"+i).start();
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //2个生产者线程
        for (int i = 0; i < 2; i++) {

            Runnable p=new Runnable() {             
                @Override
                public void run() {
                    for (int j = 0; j < 26; j++) {
                        myCon.put(Thread.currentThread().getName()+" "+j);
                    }

                }
            };

            new Thread(p,"p"+i).start();
        }


        Runnable p=new Runnable() {             
            @Override
            public void run() {
                    System.out.println(myCon.getCount());
            }
        };

        new Thread(p,"count").start();

    }

}

总结
这里做个笔记,我感觉面试可能会碰到,所以可以收藏看看。

你可能感兴趣的:(java多线程)