生产者消费者模式,多线程synchrized的自我理解

作为即将毕业的应届生,多线程锁是面试高频,为了能够加深自己理解,也便自己以后能够及时复习,为此写了一篇自我理解的消费者生产者 synchrized锁的理解。

这里实现多线程之间的通信,采用了管程法,消费者生产者之间需要一个缓冲区,可以理解为一个仓库,废话不多说直接上代码;

定义一个缓冲区:含有二个属性,产品,计数器。对共享资源来说,缓冲区含有生产和消费两个方法,但按常理来说需要满足两个条件,若库存数量等于缓冲区的最大值,则生产者的线程需要等待(this.wait),消费者线程一直消费库存,并通知生产者可以继续生产 this.notifyAll()唤醒全部线程(synchrized无法指定唤醒具体线程,后续的lock锁将可以实现),同理消费者等待和生产者主动唤醒所有线程也类同。重要一点,此判断不能用if,只能用while ,因为if只会判定一次,while 每一次都判断,若多个消费者和生产者,将会造成异常,如果count为10时候,两个并发个线程都拿到10,数组越界异常(这里理解还不够充分)

class Chicken {
      String id;

    public Chicken(int id) {
        this.id = id;
    }
}
class  SynContaier{
    //容器大小
     Chicken [] chickens=new Chicken[100];
     Integer count = 0;
    ///生产者
     public synchronized void  push(Chicken chicken)
     {

         while (chickens.length==count)
         {
             try {
                 System.out.println(Thread.currentThread().getName()+"------->>>>>>在等待");
                 this.wait();
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         //System.out.println("库存剩余"+count+"只鸡");
         chickens[count]=chicken;
         count++;
         //通知消费者消费
         this.notifyAll();
     }

     //消费者消费产品
    public   Chicken pop()
    {
        synchronized(this){
            while (count==0)
            {
                try {
                    System.out.println(Thread.currentThread().getName()+"---------->在等待");
                    this.wait();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println("库存剩余"+count+"只鸡");
            Chicken chicken=chickens[count-1];
            count--;
            this.notifyAll();()
            return chicken;
        }

    }


}

 消费者 和生产者类:

class Productor implements Runnable{
    SynContaier contaier;
    Integer i=0;
    public Productor(SynContaier contaier)
    {
        this.contaier=contaier;
    }
    @Override
    public  synchronized void run() {
        //锁住i 效率变低
        while (true)
        {
            contaier.push(new Chicken(Thread.currentThread().getName()+"生产的第"+i));
            i++;
            System.out.println(Thread.currentThread().getName()+"---->"+"生产了"+i+"鸡");
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

//消费者
class  Consumer implements  Runnable{
    SynContaier contaier;

    public Consumer(SynContaier contaier)
    {
        this.contaier=contaier;
    }

    @Override
    public synchronized  void run() {

        while (true)
        {

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"---->消费了"+contaier.pop().id+"鸡");



        }

    }
}

测试类:

//生产消费模型
public class TestPC {
    public static void main(String[] args) {
         SynContaier contaier=new SynContaier();
        for (int i = 0; i < 10; i++) {


            new Thread(new Productor(contaier),"生产者"+i).start();
        }
        for (int i = 0; i < 5; i++) {
            new Thread(new Consumer(contaier),"消费者"+i).start();
        }

    }

}

 运行结果:

生产者消费者模式,多线程synchrized的自我理解