`
cjf068
  • 浏览: 34405 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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();
		}
	}
}
分享到:
评论

相关推荐

    Feng-Many-Birds-One-Stone-Exploiting-A-Single-SQLite-Vulnerabili

    缓冲区溢出则可能导致程序崩溃,或者更严重的是,攻击者可以利用它来执行任意代码,获得系统控制权。 在实际应用中,攻击者可能会利用这种漏洞进行数据盗窃、系统瘫痪甚至横向渗透。例如,如果一个移动应用使用易受...

    Many_Birds,_One_Stone__Exploiting_a_Single_SQLite_Vulnerabili

    而CVE-2017-10989则涉及到对RTree blob处理不当,导致缓冲区越界读取。 【SQL语句触发的内存破坏】 SQLite解释器允许更灵活的方式来触发SQL语句中的bug。如CVE-2015-3414和CVE-2015-3415所示,不正确的collation...

    Hibernate的配置详解

    2. 一对多关系(One-to-Many): - 一个实体对象可以对应多个其他实体对象的实例,通常在多方的一端使用`List`或`Set`来存储关联对象。映射文件中使用`set`或`list`元素表示这种关系。 3. 多对多关系(Many-to-...

    操作系统最经典三张纸

    操作系统是计算机系统的核心组成部分,它管理着系统的硬件资源和软件资源...许多对一模型(Many-to-one)是指多个用户线程映射到一个内核线程,多对多模型(Many-to-many)则是用户线程与内核线程之间存在多对多关系。

    Hibernate学习

    - **关联映射的本质**:通过`&lt;many-to-one&gt;`标签将实体类与数据库表字段关联起来。 - **User实体类**:表示用户信息。 - **Group实体类**:表示用户所属的组信息。 - **Group实体类的映射文件**:定义了Group与User...

    Java学习笔记-个人整理的

    {7.10}缓冲字符输入输出流}{113}{section.7.10} {7.11}文件常用操作}{114}{section.7.11} {7.12}对象序列化}{117}{section.7.12} {8}多线程}{121}{chapter.8} {8.1}线程的常用属性与方法}{121}{section.8.1} {...

    JAVA面试题

    例如,`Department`的映射可能包含`&lt;list&gt;`元素表示`employees`,`Employee`的映射可能包含`&lt;many-to-one&gt;`表示`department`,`&lt;set&gt;`表示`roles`。 8. **基础编程题**: - 将`count`转换为`double`:`Double....

    hibernate 教程

    一对多关联(One-To-Many Associations) 6.5. 延迟初始化(延迟加载)(Lazy Initialization) 6.6. 集合排序(Sorted Collections) 6.7. 使用&lt;idbag&gt;&lt;br&gt;6.8. 双向关联(Bidirectional Associations)...

    hibernate

    一对多关联(One-To-Many Associations) 6.5. 延迟初始化(延迟加载)(Lazy Initialization) 6.6. 集合排序(Sorted Collections) 6.7. 使用&lt;idbag&gt;&lt;br&gt;6.8. 双向关联(Bidirectional Associations)...

    Yii2.0表关联查询实例分析

    - `hasOne()`:表示一对多的关联关系。在一对多关系中,一个表(例如客户表)会有一个或多个相关联的记录在另一个表(例如订单表)中。例如,`$customer-&gt;orders` 会返回该客户下的所有订单数组。 - `hasMany()`:...

    北师大版模块三unit7——Unit9短语归纳.pdf

    2. **as many as** - 多达:用来表示数量,强调达到或接近某个数量。 3. **get into trouble** - 陷入麻烦:指遇到问题或困难,可能需要解决或摆脱。 4. **make it to** - 到达:成功抵达某个地方或完成某件事。 ...

Global site tag (gtag.js) - Google Analytics