JUC练习2——java生产者消费者demo

以下的代码示例:先使用了synchronized关键字来实现生产者消费者,而后使用了JUC中的lock及其condition来实现生产者消费者

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class JucTest1
{
    public static void main(String[] args)
    {
        Ticket ticket = new Ticket();
        for (int i=0;i<4;i++)
        {
            new Thread(()->
            {
                try {
                    for (int j=0;j<10;j++)
                    {
                        ticket.produce();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },"A"+i).start();
            new Thread(()->
            {
                try {
                    for (int j=0;j<10;j++)
                    {
                        ticket.consumer();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },"B"+i).start();
        }

        JUCTicket jucTicket = new JUCTicket();
        for (int i=0;i<4;i++)
        {
            new Thread(()->
            {
                for (int j=0;j<10;j++)
                {
                    jucTicket.produce();
                }
            },"C"+i).start();
            new Thread(()->
            {
                for (int j=0;j<10;j++)
                {
                    jucTicket.consumer();
                }
            },"D"+i).start();
        }
    }
}
//使用synchronized来模拟生产者消费者问题
class Ticket
{
    private int number = 0;
    //使用synchronized来实现并发,synchronized可以锁当前对象
    synchronized void produce() throws InterruptedException {
        //如果使用if判断存在虚假唤醒问题,也就是两个线程同时进入,所以我们一般把等待的内容放到where中
        while (number != 0)
        {
            //等待消费者消费
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"生产后,number="+number);
        //通知其它线程我生产完成了
        this.notifyAll();
    }

    synchronized void consumer() throws InterruptedException {
        while (number == 0)
        {
            //等待生产者生产
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"消费后,number="+number);
        //通知其它线程我消费完成了
        this.notifyAll();
    }
}

//使用lock锁来模拟生产者消费者问题
class JUCTicket
{
    private int number = 0;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    //condition.signalAll();相当于this.notifyAll();
    //condition.await();相当于this.wait();
    //使用synchronized来实现并发,synchronized可以锁当前对象
    void produce(){
        lock.lock();
        try
        {
            while (number != 0)
            {
                //等待消费者消费
                condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"生产后,number="+number);
            //通知其它线程我生产完成了
            condition.signalAll();
        }catch (Exception e)
        {
            e.printStackTrace();
        }finally
        {
            lock.unlock();
        }
    }

    void consumer(){
        lock.lock();
        try
        {
            while (number == 0)
            {
                //等待生产者生产
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName()+"消费后,number="+number);
            //通知其它线程我生产完成了
            condition.signalAll();
        }catch (Exception e)
        {
            e.printStackTrace();
        }finally
        {
            lock.unlock();
        }
    }
}

运行的结果:生产者只能生产一个,生产后,需要等待其它消费者进行消费,消费者消费完成后通知生产继续生产

B0消费后,number=0
A0生产后,number=1
B0消费后,number=0
A1生产后,number=1
B1消费后,number=0
A0生产后,number=1
B2消费后,number=0

上一篇:PHP获得微信用户的OpenID,然后再通过OpenID和access_token查询用户信息


下一篇:powerbuilder 函数 indirect 的用法