java 多线程的生产者-消费者 实现

      Java 语言实现生产者 --  消费者模式,本文采用1个生产者和3个消费者,以体现多线程并发过程中应该注意的地方。

      其中,容器采用java.util.concurrent.LinkedBlockingQueue,这是一个并发容器,包concurrent就是Java专门为实现并发而提供的一组工具包。

 

      思路:一个容量为100的容器,一个生产者(一个线程)不断向其中添加从0开始的整数,如果超出容器范围则线程阻塞1s,与此同时,三个消费者(三个线程,当然也可以是更多~)不断向容器拿出整数,如果容器取空,则线程阻塞1s。

 

      对容器操作是主要的部分,此处要考虑线程的并发性,而此时因为LinkedBlockingQueue是线程安全的,因此就可以不用加锁和Syncholized关键字等。多方便啊~

 

public class BlockingQueueTest
{
	private BlockingQueue<Integer> bq;
	private int M=100;
	public BlockingQueueTest()
	{
		bq = new LinkedBlockingQueue<>(M);
	}
	public boolean putIn(int n)
	{
		if(bq.size()<M)
		{
			bq.add(n);
			return true;
		}else{
			return false;
		}
	}
	public int getOut()
	{
		if(bq.size()>0)
		{
			return bq.poll();
			
		}else{
			return -1;
		}
	}
}

          容器实现了,就实现生产者和消费者这两个线程吧,线程的实现主要有两种:一种是继承父类Thread,第二种是实现接口Runnable();此处实现接口—>减少类之间的耦合度。

 

public void run()
	{
		while (true)
		{
			for (int i=0; i<100000;i++)
			{
				if (bqt.putIn(i))
				{
				 dataOut(Thread.currentThread().getName()+"     put:"+i);
				} else
				{
					 dataOut("Queue is full ! Sleep for 1s");
					try
					{
						Thread.sleep(1000);
					} catch (InterruptedException e)
					{
						e.printStackTrace();
					}
				}
			}
		}
	}

          消费者则更加简单:

public void run()
	{
		while (true)
		{
			int i = bqt.getOut();
			if(i!=-1)
			{
				dataOut(Thread.currentThread().getName() + " get  " + i);
			}else{
				dataOut(Thread.currentThread().getName() +": Queue is empty! Sleep for 1s");
				try
				{
					Thread.sleep(1000);
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		}
		
	}

       其中输出的方法实现:(此处可根据具体情况改变)

public void dataOut(String s)
	{
		System.out.println(s);
	}

 

       主要的几个都实现了,生成测试类:

public static void main(String[] args) throws Exception
	{
		BlockingQueueTest bqt = new BlockingQueueTest();
		Thread f = new Thread(new Productor(bqt));
		Thread a = new Thread(new Consumer(bqt));
		Thread a1 = new Thread(new Consumer(bqt));
		Thread a2 = new Thread(new Consumer(bqt));
		f.setName("Productor");
		a.setName("consumer 1");
		a1.setName("consumer 2");
		a2.setName("consumer 3");
		f.start();
		a.start();
		a1.start();
		a2.start();
	}

  

        最后贴个结果图把:



 

源码在这里~~

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值