Many2One缓冲

多线程并发操作中,为了尽量减少同步锁的开销,一般都会尽可能减少同步操作。以下是一个多线程写入,写入操作需要同步,读取操作需要部分同步;读取操作的同步发生在缓冲区交换的时候。
以下是简单的java实现
package org.jf;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 * 
*    
* 项目名称:Util   
* 类名称:MyBuffer   
* 类描述:  多线程写入 单线程读取 
* 创建人:Administrator   
* 创建时间:Mar 6, 2012 9:48:44 AM   
* 修改人:Administrator   
* 修改时间:Mar 6, 2012 9:48:44 AM   
* 修改备注:   
* @version    
*
 */
public class Many2OneBuffer <T>{
	
	private Object writeLock;
	
	private int writeIndex=0;
	private int readIndex=0;
	
	private Object [] writeBuffer;
	private Object [] readBuffer;
	
	private int limit = -1;
	private int readLimit = -1;
	private int capacity ;

	
	public Many2OneBuffer(int capacity)
	{
		this.capacity=capacity;
		writeBuffer = new Object[capacity];
		readBuffer = new Object[capacity];
		writeLock = new Object();
	}
	
	public Many2OneBuffer() 
	{
		this(500);
	}
	
	public boolean  put(T obj)throws InterruptedException
	{
		synchronized(writeLock)
		{
			while(writeIndex == capacity)
			{
				writeLock.wait();
			}
			writeBuffer[writeIndex++] = obj;
			limit++;
			
			writeLock.notifyAll();
			return true;		
		}
	}
	
	public boolean put(T obj,int timeout)throws InterruptedException
	{
		synchronized(writeLock)
		{
			if(writeIndex == capacity)
			{
				writeLock.wait(timeout*1000);
			}
			
			if(writeIndex == capacity)
			{
				return false;
			}
			
			writeBuffer[writeIndex++] = obj;
			limit++;
			
			writeLock.notify();
			return true;		
		}
	}

	public T poll()throws InterruptedException
	{
		Object obj = null;
		
		if(readLimit == -1)
		{
			if(limit == -1)
			synchronized(writeLock)
			{
				while(limit == -1)
					writeLock.wait();
			}
//			if(limit== -1)
//				return  null;
			
			synchronized(writeLock)
			{
				//交换读写缓冲
				Object [] tmp = null;
				tmp = this.writeBuffer;
				this.writeBuffer = this.readBuffer;
				this.readBuffer = tmp;
				readLimit = limit;
				this.readIndex = 0;
				this.writeIndex = 0;
				this.limit = -1;
				writeLock.notify();
			}
			
		}
	 
		//readLimit 必定大于0
		if(readIndex == readLimit )
		{
			obj = readBuffer[readIndex++];
			readLimit = -1;
		}
		else //if(readIndex<readLimit) readIndex 必定小于等于 readLimit
		{
			obj = readBuffer[readIndex++];
		}
//		
		return (T)obj;
	}
	
	
	public boolean isFull()
	{
		return this.writeIndex == this.capacity;
	}
	
	public static void main(String args[]) throws InterruptedException
	{
		Many2OneBuffer buffer = new Many2OneBuffer(500);
		WriteThread writeThread = new WriteThread(buffer);
		writeThread.start();
		
		PutThread putThread1 = new PutThread(buffer,"PutThread1");
		PutThread putThread2 = new PutThread(buffer,"PutThread2");
		PutThread putThread3 = new PutThread(buffer,"PutThread3");
		PutThread putThread4 = new PutThread(buffer,"PutThread4");
		putThread1.start();
		putThread2.start();
		putThread3.start();
		putThread4.start();

		
		
		Thread.sleep(6*10*1000);
		putThread1.exit();
		putThread2.exit();
		putThread3.exit();
		putThread4.exit();
		writeThread.exit();
	}
	

}

class PutThread extends Thread
{
	Many2OneBuffer buffer ;
	String rawStr;
	boolean exit = false; 
	PutThread(Many2OneBuffer myBuffer,String rawStr)
	{
		buffer = myBuffer;
		this.rawStr = rawStr;
	}
	
	public void run()
	{
		int i = 0;
		while(!exit)
		{
			try {
				boolean succ = buffer.put(rawStr+"_"+i);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
//			if(!succ)
//				System.out.println("put failed :"+rawStr+"_"+i);
			i++;
		}
//		System.out.println("put thread exit_"+this.rawStr);
	}
	
	public void exit()
	{
		exit = true;
		this.interrupt();
	}
	
}

class WriteThread extends Thread
{
	Many2OneBuffer buffer ;
	boolean exit = false;
	WriteThread(Many2OneBuffer myBuffer)
	{
		buffer = myBuffer;
	}
	
	public void exit()
	{
		exit = true;
	}
	
	public void run()
	{
		try {
			BufferedWriter bw = new BufferedWriter(new FileWriter("e:/write.txt",false));
			int count = 0;
			while(!exit)
			{
				Object obj = buffer.poll();
				if(obj!=null)
				{
					bw.write(obj.toString()+"\n");
					count++;
					bw.flush();
					if(count==100)
					{
						this.sleep(100);
						count = 0;
					}
				}
			}
			System.out.println("write thread exit");
			bw.flush();
			bw.close();
			
		} catch (IOException e) 
		{
			e.printStackTrace();
		} catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
	}
}

你可能感兴趣的:(man)