`
braveCS
  • 浏览: 72288 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

多线程之生产者消费者

阅读更多
也是一个笔试题,诸多借口没做好。还是自己没理解透多线程。吾日三省吾身。
代码很多copy JDK6.0的API,也有改写一点点。
class Product {}

/**
 *该类是JDK6.0API中的Condition中的示例。
 *此外现成的BlockingQueue的实现:用于生产者-使用者队列,而且是线程安全的。
 *BlockingQueue的实现的所有排队方法都可以使用内部锁或其他形式的并发控制来自动达到它们的目的。
 */
class Storage<T>
{
	private int capacity;
	private int count;
	private T[] items;
	int putptr, takeptr;
	
	private Lock lock = new ReentrantLock();
	private Condition notFull  = lock.newCondition(); 
	private Condition notEmpty = lock.newCondition(); 
	
	public Storage(int capacity,Class<?> type)
	{
		this.capacity=capacity;
		items=(T[])Array.newInstance(type, capacity);	
	}
	 
	public void put(T x) throws InterruptedException 
	{
		lock.lock();
		try 
		{
			while (count == capacity) 
				notFull.await();
			items[putptr] = x; 
			if (++putptr == capacity) 
				putptr = 0;
			++count;
			notEmpty.signal();
	    } 
		finally 
	    {
	       lock.unlock();
	    }
	}

	public T take() throws InterruptedException 
	{
		lock.lock();
		try 
		{
			while (count == 0) 
				notEmpty.await();
			T x = items[takeptr]; 
			if (++takeptr == capacity) 
				takeptr = 0;
			--count;
			notFull.signal();
			return x;
	    }
		finally 
		{
			lock.unlock();
	    }
	}
}

/**
 * 生产者、消费者来自JDK6.0 API BlockingQueue里的示例
 */
class Producer implements Runnable 
{
	public void run() 
	{		
		while(!Thread.currentThread().isInterrupted()) 
		{
			try{
				cLock.lockInterruptibly();
				try{
					if(count>32)
					{
						Thread.currentThread().interrupt();
						System.out.println(name+":退出");
					}
					storage.put(produce());
				}finally{cLock.unlock();}
			}catch (InterruptedException ex){Thread.currentThread().interrupt(); }
		}		
	}
	
	private final Storage<Product> storage;
	private String name;
	private static int count;
	private static Lock cLock=new ReentrantLock() ;
	public Producer(Storage<Product> storage,String name) 
	{ 
		this.storage=storage;
		this.name=name;
	}
	private Product produce() throws InterruptedException 
	{
		Thread.sleep(600);
		cLock.lockInterruptibly();
		try{
			count++;
			System.out.println(name+"生产第"+count+"个");
			return new Product();
		}finally{cLock.unlock();}		
	}	  
}

class Consumer implements Runnable 
{
	public void run() 
	{		
		while(!Thread.currentThread().isInterrupted())
		{				
			try{
				cLock.lockInterruptibly();
				try{
					if(count>32)
					{
						Thread.currentThread().interrupt();
						System.out.println(name+":退出");
					}
					consume(storage.take());
				}finally{cLock.unlock();}
			} catch (InterruptedException ex){Thread.currentThread().interrupt(); }
		}	
	}
	
	private final Storage<Product> storage;
	private String name;
	private static int count;
	private static Lock cLock=new ReentrantLock() ;
	public Consumer(Storage<Product> storage,String name) 
	{ 
		this.storage=storage;
		this.name=name;
	}	
	void consume(Product product) throws InterruptedException 
	{
	   Thread.sleep(800);
	   cLock.lockInterruptibly();
	   try{
		   count++;
		   System.out.println(name+"消费第"+count+"个");
	   }finally{cLock.unlock();}	
	}	
}

public class Cs 
{
	public static void main(String[] args)
	{	
		Storage<Product> q = new Storage<Product>(20,Product.class);
		Producer p = new Producer(q,"p");
		Consumer c1 = new Consumer(q,"c1");
		Consumer c2 = new Consumer(q,"c2");
		new Thread(p).start();
		new Thread(c1).start();
		new Thread(c2).start();
	}	
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics