进程同步-生产者消费者问题

本文介绍了一个简单的生产者消费者模式实现,通过同步堆栈类管理生产与消费过程,并使用Java线程进行模拟。演示了如何利用synchronized关键字和wait/notify方法来确保线程间的正确同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * Created by Leon on 2017/5/23.
 * 生产者消费者问题
 */
public class ProducerConsumer
{
    public static void main(String[] args)
    {
        syncstack ss=new syncstack();
        Producer p=new Producer(ss);
        Consumer c=new Consumer(ss);

        new Thread(p).start();//一个生产者
        new Thread(p).start();//一个生产者
        new Thread(p).start();//一个生产者
        new Thread(c).start();//一个消费者
    }
}

class wotou
{
    int id;
    wotou(int id)
    {
        this.id=id;
    }

    @Override
    public String toString()
    {
        return "wotou:"+id;
    }
}

class syncstack
{
    int index=0;//当前装到第几个wotou了
    wotou[] arrWT=new wotou[6];

    public synchronized void push(wotou wt)
    {
        while(index==arrWT.length)//用if比较危险,如果出现InterruptedException会跳出if语句出现错误
        {
            try
            {
                this.wait();//Object中的wait方法:当前的正在访问这个对象的线程wait;
                // 只能在synchronized的方法中用;wait后放弃对于锁的所有权
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
       //this.notify();//叫醒正在wait的线程;与wait方法成对出现
        this.notifyAll();//叫醒其他多个线程,不能叫醒自己;多个生产者消费者的时候使用
        arrWT[index]=wt;
        index++;
    }
    public synchronized wotou pop()
    {
        while(index==0)
        {
            try
            {
                this.wait();
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        //this.notify();
        this.notifyAll();
        index--;
        return arrWT[index];
    }
}

class Producer implements Runnable
{
    syncstack ss=null;
    Producer(syncstack ss)
    {
        this.ss=ss;
    }

    @Override
    public void run()
    {
        for (int i=0;i<20;i++)//每人生产20个wotou
        {
            wotou wt=new wotou(i);
            ss.push(wt);
            System.out.println("生产了:"+wt);
            try
            {
                Thread.sleep((int)(Math.random()*2));//1000个毫秒以内随机睡眠,控制生产速度
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}
class Consumer implements Runnable
{
    syncstack ss=null;
    Consumer(syncstack ss)
    {
        this.ss=ss;
    }

    @Override
    public void run()
    {
        for (int i=0;i<60;i++)//共有三个生产者生成60个wotou
        {
            wotou wt=ss.pop();
            System.out.println("消费了:"+wt);
            try
            {
                Thread.sleep((int)(Math.random()*1000));
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}



总结:wait()和sleep()的区别

wait()是Objec的方法,放弃进程锁

sleep()是Thread的方法,不放弃进程锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值