好记性不如铅笔头

java, think_in_java, 编程

《Java编程思想》读书笔记:Condition

最近在整理 Java 的多线程相关的技术,这里备份下关于【 Condition 】代码。

github:

https://github.com/cstriker1407/think_in_java 】

ConditionTest.java类

public class ConditionTest
{
	public static void test()
	{
		LinkedList<Integer> list = new LinkedList<Integer>();
		Lock lock = new ReentrantLock();//锁对象  
		Condition inCond = lock.newCondition();
		Condition outCond = lock.newCondition();

		ConditionProducer p1 = new ConditionProducer(0, lock, inCond, outCond, list);
		
		ConditionConsumer c1 = new ConditionConsumer(0, lock, inCond, outCond, list);
		ConditionConsumer c2 = new ConditionConsumer(1, lock, inCond, outCond, list);
		
		p1.start();
		c1.start();
		c2.start();
	}
}
class ConditionProducer extends Thread
{
	private int id;
	private Lock lock;
	private Condition inCond;
	private Condition outCond;
	private LinkedList<Integer> list;
	
	public ConditionProducer(int id, Lock lock, Condition inCond, Condition outCond, LinkedList<Integer> list)
	{
		super();
		this.id = id;
		this.lock = lock;
		this.inCond = inCond;
		this.outCond = outCond;
		this.list = list;
	}

	@Override
	public void run()
	{
		for (int i = 0; i < 100; i++)
		{
			lock.lock();
			while(list.size() == 10)
			{
				System.out.println("list is full,begin to await");
				try
				{
					inCond.await();//与此 Condition 相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
			System.out.println("list begin to produce");
			
			list.offer(i);
			System.out.println("线程" + id + " 放入了"+ i);

			outCond.signalAll();
			
			lock.unlock();
			
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class ConditionConsumer extends Thread
{
	private int id;
	private Lock lock;
	private Condition inCond;
	private Condition outCond;
	private LinkedList<Integer> list;
	
	public ConditionConsumer(int id, Lock lock, Condition inCond, Condition outCond, LinkedList<Integer> list)
	{
		super();
		this.id = id;
		this.lock = lock;
		this.inCond = inCond;
		this.outCond = outCond;
		this.list = list;
	}

	@Override
	public void run()
	{
		for (int i = 0; i < 50; i++)
		{
			lock.lock();
			while(list.size() == 0)
			{
				System.out.println("线程" + id + "  list is empty,begin to await");
				try
				{
					outCond.await();
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
			System.out.println("线程" + id + "  list begin to consume");
			
			int x = list.poll();
			System.out.println("线程" + id + " 获取了"+ x);
			inCond.signalAll();
			
			lock.unlock();
			
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

部分日志打印:

list begin to produce
线程0 放入了11
list is full,begin to await
线程0  list begin to consume
线程0 获取了2
list begin to produce
线程0 放入了12
list is full,begin to await
线程1  list begin to consume
线程1 获取了3
list begin to produce
线程0 放入了13
list is full,begin to await
线程0  list begin to consume
线程0 获取了4
list begin to produce
线程0 放入了14
list is full,begin to await
线程1  list begin to consume
线程1 获取了5
list begin to produce
线程0 放入了15
list is full,begin to await
线程0  list begin to consume
线程0 获取了6

备注:

这个例子是用 Condition 实现的消费者-生产者模型,使用了 await/signalAll 方法对生产和消费分别控制,而不用 wait/notify ,可以实现更加精细化的控制。

Leave a Reply

5 − 2 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据