生产者、消费者

/*
 *生产者和消费者:此例中使用了新的同步机制,以及通过改变标记进行通讯的行为。
 */

package classfile;
import java.util.concurrent.locks.*;

public class ProducerAndConsumerDemo
{
	public static void main(String[] args)
	{
		Resource r = new Resource();

		new Thread(new Producer(r)).start();
		new Thread(new Consumer(r)).start();
		new Thread(new Consumer(r)).start();
	}
}

/**
 *本类用于模拟资源,拥有对资源进行生产和消费的方式。多线程安全。
 */
class Resource//资源要进行单独的封装
{
	private String name;
	private int count = 1;//记录资源的数量,同时用于控制对资源的生产和消费行为。
	private boolean flag = false;//让生产行为和消费行为交替进行,一种通讯方式。

	Lock lock = new ReentrantLock();//让锁变得可控

	Condition pro = lock.newCondition();//锁上的两个事件
	Condition con = lock.newCondition();
	

	public int getNum()//通过资源的数量来控制生产和消费的行为
	{
		return count;
	}
	
	/**
	 *此方法完成生产资源的行为,并在控制台上输出生产行为。多线程安全。
	 *
	 *@param name
	 *				资源的名称
	 */
	public void set(String name)
	{
		lock.lock();
		try
		{
			while(flag)
			{
				try
				{
					pro.await();
				}
				catch (Exception e)
				{
				}
			}
			//不管是一直在等待的消费者,还是新加入的消费者,都会执行到这里。通过对商品数量的判断,就可以退出程序。
			if(count==100)//生产任务完成,程序退出
			{
				return;
			}	
			
			this.name = name+"---"+count;
			System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);

			flag = true;
			con.signalAll();
		}
		finally
		{
			lock.unlock();//释放锁的动作必须被执行
		}
		
	}
	
	/**
	 *此方法完成消耗资源的行为,并在控制台上输出消费的信息。多线程安全。
	 */
	public void get()
	{
		lock.lock();
		try
		{
			while(!flag)//消费完最后的商品后,不管是一直在等待的消费者,还是新加入的消费者,都会进入这个循环中。通过对商品数量的判断,就可以退出程序。
			{
				if(count==100)//消费额度完成,程序退出,避免程序挂起。
				{
					return;
				}

				try
				{
					con.await();
					
				}
				catch (Exception e)
				{
				}
			}

			System.out.println(Thread.currentThread().getName()+".....消费者....."+this.name);
			count++;//消费完之后,再将商品的编号自增,可以让生产和消费同步。

			flag = false;
			pro.signalAll();
			
		}
		finally
		{
			lock.unlock();
		}
		
		
	}
}

/**
 *本类用于模拟生产者。
 */
class Producer implements Runnable
{
	private Resource r;
	
	/**
	 *生产者一被创建,即拥有资源
	 *
	 *@param r
	 *			一种资源
	 */
	public Producer(Resource r)
	{
		this.r = r;
	}
	/**
	 *重写父类的run方法。
	 */
	public void run()
	{
		while(r.getNum()<100)
		{
			r.set("商品");
		}
	}
}

/**
 *本类用于模拟消费者。
 */
class Consumer implements Runnable
{
	private Resource r;
	
	/**
	 *消费者一被创建,即拥有资源
	 *
	 *param r
	 *			一种资源
	 */
	public Consumer(Resource r)
	{
		this.r = r;
	}

	/**
	 *重写父类的run方法。
	 */
	public void run()
	{
		while(r.getNum()<100)
		{
			r.get();
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值