H2O与Java线程同步

Java 5以前的线程同步采用syncronized和wait,notify,notifyAll来实现,比较粗糙。之后有了Lock和Condition。
ReentrantLock的简单lock,unlock相当于syncronized。而通过condition的signal和await,可以实现更细粒度的控制。

http://www.cnblogs.com/yaowukonga/archive/2012/08/27/2658329.html  http://blog.csdn.net/vernonzheng/article/details/8288251 http://blog.csdn.net/fw0124/article/details/6672522

下面这个例子是本人的实现,望指正。基本意思是H函数会产生H分子,O函数产生O分子,每个线程产生一个分子,当有两个H一个O时,这三个线程退出。

实现思路是用Condition的Queue来存顺序,这样能够控制线程退出的顺序(也能够根据需求实现不同的顺序),而且能避免惊群。测试用例简单测试了当H和O不足和超出时的情形。

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

class H2O implements Runnable
{
	static final Lock lock = new ReentrantLock();
	static LinkedList<Condition> hQueue = new LinkedList<Condition>();
	static LinkedList<Condition> oQueue = new LinkedList<Condition>();
	
	private String particle;
	private int id;
	
	public H2O(String particle, int id)
	{
		this.particle = particle;
		this.id = id;
	}

	public void run()
	{
		if (particle.equals("h"))
		{
			H(id);
		}
		else if (particle.equals("o"))
		{
			O(id);
		}
	}
	
	public static void H(int hid)
	{
		lock.lock();
		try {
			if (hQueue.size() >= 1 && oQueue.size() >= 1)
			{
				// generate water
				Condition hc = hQueue.poll();
				Condition oc = oQueue.poll();
				hc.signal();
				oc.signal();
				System.out.println("H:" + hid);
			}
			else
			{
				// wait
				Condition c = lock.newCondition();
				hQueue.add(c);
				c.await();
				System.out.println("H:" + hid);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public static void O(int oid)
	{
		lock.lock();
		try {
			if (hQueue.size() >= 2)
			{
				// generate water
				Condition hc1 = hQueue.poll();
				Condition hc2 = hQueue.poll();
				hc1.signal();
				hc2.signal();
				System.out.println("O:" + oid);
			}
			else
			{
				// wait
				Condition c = lock.newCondition();
				oQueue.add(c);
				c.await();
				System.out.println("O:" + oid);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
}

public class Solution {
    public static void main(String args[]) throws InterruptedException {
    	for (int i = 1; i <= 6; i++)
    	{
    		new Thread(new H2O("h", i)).start();
    	}
    	Thread.sleep(1000);
    	for (int i = 1; i <= 6; i++)
    	{
    		new Thread(new H2O("o", i)).start();
    	}
    	Thread.sleep(1000);
    	for (int i = 7; i <= 36; i++)
    	{
    		new Thread(new H2O("h", i)).start();
    	}
    	Thread.sleep(1000);
    	for (int i = 7; i <= 12; i++)
    	{
    		new Thread(new H2O("o", i)).start();
    	}
    	Thread.sleep(1000);
    	for (int i = 13; i <= 18; i++)
    	{
    		new Thread(new H2O("o", i)).start();
    	}
    }
}

  

posted @ 2013-11-18 22:14  阿牧遥  阅读(...)  评论(...编辑  收藏