`
臻是二哥
  • 浏览: 187874 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
Group-logo
Java技术分享
浏览量:0
社区版块
存档分类
最新评论

JAVA并发- 典型连接池的实现

阅读更多
package com.xyz.connpool;

public interface IConnection {
	/**
	 * 关闭当前连接
	 */
	public void close();
	/**
	 * 销毁当前连接
	 */
	public void destroy();
	//应该具备的其他方法
}


public class Connection implements IConnection {
	private String name;
	private IConnPool connPool;
	public Connection(IConnPool connPool,String name){
		this.connPool=connPool;
		this.name=name;
	}
	@Override
	public void close() {
		this.connPool.releaseConn(this);
	}
	@Override
	public void destroy() {
		System.out.println("destroy connection---"+name);
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		super.toString();
		return name;
	}

}


public interface IConnPool {
	 /**
	  * 获得一个可用连接,超过最大连接数时线程等待,直到有有连接释放时返回一个可用连接或者超时返回null 
	  * @param maxWaitTime
	  * @return
	  */
	public IConnection getConn();
	/**
	 * 将释放的空闲连接加入空闲连接池
	 * @param conn
	 */
	public void releaseConn(IConnection conn);
	/**
	 * 销毁连接池
	 */
	public void destroy();
	/**
	 * 获取当前线程对应的连接
	 * @return
	 */
	public IConnection getCurrentConn();
}


import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class ConnPool implements IConnPool {
	private int initNum;
	private int maxNum;
	private int hasAlready;
	private long maxWaitTime;
	private final List<IConnection> freeConnList;
	private final List<IConnection> activeConnList;
	private static ThreadLocal<IConnection> threadLocalVar=new ThreadLocal<IConnection>(){
		protected IConnection initialValue() {
			return null;
		};
	};
	public ConnPool(){
		this.initNum=3;
		this.maxNum=5;
		this.hasAlready=0;
		this.maxWaitTime=1000;
		this.freeConnList=new ArrayList<IConnection>(maxNum);
		this.activeConnList=new ArrayList<IConnection>(maxNum);
		init();
	}
	public ConnPool(int initNum,int maxNum,long maxWaitTime){
		this.initNum=initNum;
		this.maxNum=maxNum;
		this.hasAlready=0;
		this.maxWaitTime=maxWaitTime;
		this.freeConnList=new ArrayList<IConnection>(maxNum);
		this.activeConnList=new ArrayList<IConnection>(maxNum);
		init();
	}
	private void init(){
		for(int i=0;i<this.initNum;i++){
			synchronized (this) {
				this.freeConnList.add(new Connection(this,UUID.randomUUID().toString()));
				hasAlready++;
			}
		}
	}
	@Override
	public synchronized IConnection getConn()  {
			IConnection conn=null;
			if(!this.freeConnList.isEmpty()){
				conn=this.freeConnList.remove(0);
				if(conn!=null)
					threadLocalVar.set(conn);//为线程绑定连接
				this.activeConnList.add(conn);
				return conn;
			}
			if(hasAlready<maxNum){
				conn = new Connection(this,UUID.randomUUID().toString());
				hasAlready++;
				if(conn!=null)
					threadLocalVar.set(conn);//为线程绑定连接
				this.activeConnList.add(conn);
				return conn;
			}
			try {
				this.wait(maxWaitTime);
				if(!this.freeConnList.isEmpty()){
					conn=this.freeConnList.remove(0);
					if(conn!=null)
						threadLocalVar.set(conn);//为线程绑定连接
					this.activeConnList.add(conn);
					return conn;
				}
				return null;
			} catch (InterruptedException e) {
				e.printStackTrace();
				return null;
			}
	}
	@Override
	public synchronized void releaseConn(IConnection conn) {
		if(this.activeConnList.contains(conn)){
			this.freeConnList.add(conn);
			this.activeConnList.remove(conn);
			threadLocalVar.remove();
			this.notify();
                 }
	}
	@Override
	public synchronized void destroy() {
		IConnection conn=null;
		int temp=this.freeConnList.size();
		for(int i=0;i<temp;i++){
			conn=this.freeConnList.remove(0);
			conn.destroy();
		}
		temp=this.activeConnList.size();
		for(int i=0;i<temp;i++){
			conn=this.activeConnList.remove(0);
			conn.destroy();
		}
		conn=null;
		this.hasAlready=0;
	}
         @Override
	public IConnection getCurrentConn() {
		return threadLocalVar.get();
	}
	
}



package com.xyz.connpool;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ConnPoolManager {
	private int initConnNum;
	private int maxConnNum;
	private long maxWaitTime;
	// 连接池存放
	public Map<Integer,IConnPool> pools=new ConcurrentHashMap<Integer, IConnPool>();
//	public Hashtable<Integer,IConnPool> pools = new Hashtable<Integer, IConnPool>();
	
	public ConnPoolManager(int initConnNum,int maxConnNum, long maxWaitTime){
		this.initConnNum=initConnNum;
		this.maxConnNum=maxConnNum;
		this.maxWaitTime=maxWaitTime;
		init();
	}
	
	// 初始化所有的连接池
	private void init(){
		for(int hostId =0;hostId<3;hostId++){
			ConnPool connPool=new ConnPool(this.initConnNum,this.maxConnNum, this.maxWaitTime);
			if(connPool != null){
				pools.put(hostId,connPool);
				System.out.println("Info:Init connPool successed for hostId ->" +hostId);
			}
		}
	}
	
	/**
	 * 根据主机id获取连接池
	 * @param hostId
	 * @return
	 */
	public IConnPool getPool(int hostId){
		IConnPool pool = null;
		if(pools.containsKey(hostId)){
			 pool = pools.get(hostId);
		}
		return pool;
	}
	
	/**
	 * 获取一个到主机hostId的连接
	 * @param hostId
	 * @return
	 */
	public IConnection getConn(int hostId){
		IConnPool connPool = getPool(hostId);
		if(connPool==null){
			System.out.println("Error:Can't find this connecion pool for hostId->"+hostId);
			return null;
		}
		return connPool.getConn();
	}
	
	/**
	 * 关闭指定主机的某个链接
	 * @param hostId
	 * @param conn
	 */
	public void close(int hostId,IConnection conn){
			IConnPool pool = getPool(hostId);
			if(pool != null)
				pool.releaseConn(conn);
	}
	/**
	 * 注销某个主机的连接池
	 * @param poolName
	 */
	public void destroy(int hostId){
		IConnPool pool = getPool(hostId);
		if(pool != null){
			pool.destroy();
		}
		pools.remove(pool);
	}
	/**
	 * 注销所有连接池
	 */
	public void destory(){
		for(int hostId:pools.keySet()){
			this.destroy(hostId);
		}
	}
}



package com.xyz.connpool;
import java.util.concurrent.CountDownLatch;

public class Demo {
	public final static int REQUESTNUM=200;
	public final static int DURATION=20;
	 
	public static void main(String [] args) throws Exception{
		final CountDownLatch startGate=new CountDownLatch(1);
		final CountDownLatch endGate=new CountDownLatch(REQUESTNUM);
		
		final ConnPoolManager cpm=new ConnPoolManager(5, 10, 1000);
		final IConnection conns[] =new IConnection[REQUESTNUM];
		for(int i=0;i<REQUESTNUM;i++){
			final int flag=i;
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						startGate.await();
					} catch (InterruptedException e1) {}
					
					conns[flag]=cpm.getConn(0);
					System.out.println(conns[flag]);
					try {
						Thread.sleep(DURATION);
					} catch (InterruptedException e) {}
					cpm.close(0, conns[flag]);
					
					endGate.countDown();
				}
			}).start();
		}

		long begin = System.currentTimeMillis();
		startGate.countDown();
		endGate.await();
		long over = System.currentTimeMillis();
		System.out.println(over-begin);
//	    Thread.sleep(5000);
	    cpm.destory();
	}
}



源代码下载https://github.com/ZhenShiErGe/ConnectionPool.git
0
2
分享到:
评论

相关推荐

    单例模式----数据库连接池管理类的应用

    在Java中,实现数据库连接池的工具有很多,如Apache的DBCP、C3P0,还有更现代的HikariCP等。这些工具通常都遵循单例模式来设计,确保在整个应用生命周期中只有一个连接池实例存在,这样可以保证所有组件共享同一个...

    Java实现Socket长连接和短连接

    长连接的实现可能涉及到线程池、连接池等技术,以及异常处理和超时策略。 **3. 实现原理** - **Java Socket API**:Java提供了Socket和ServerSocket类来创建和管理TCP连接。通过ServerSocket监听特定端口,等待...

    java 数据库连接池的实现代码

    10. **第三方连接池库**:Java社区有许多成熟的数据库连接池实现,如C3P0、HikariCP、Apache DBCP和Druid等,它们提供了更丰富的功能和更好的性能,是实际项目中更常见的选择。 总的来说,数据库连接池通过有效管理...

    java数据连接池通用类(范例)

    这个"java数据连接池通用类(范例)"可能是为了提供一个可以适用于多种连接池实现的通用模板,方便开发者快速集成和管理数据库连接。 首先,我们要理解数据连接池的工作原理。当应用程序启动时,连接池会预先初始化...

    JAVA_java数据库连接池.pdf

    7. **连接池实现**:典型的连接池实现包括一个外覆类(如`DBConnectionPoolManager`,实现单例模式)用于管理连接池,以及内部类(如`DBConnectionPool`)负责连接的获取、释放和管理。此外,还需要处理无效连接和...

    mysql驱动包 mysql-connector-java-5.1.7-bin.jar

    为了解决这个问题,可以使用连接池(如C3P0、HikariCP等),预先创建并管理一批数据库连接,供多个请求复用。 10. 新版驱动支持:随着MySQL数据库的更新,驱动程序也在不断迭代。新的版本通常会提供更好的性能、更...

    JAVA_java数据库连接池(20210925001831)[借鉴].pdf

    8. **连接池实现**:典型的连接池实现包括一个外覆类(如DBConnectionPoolManager)和内部类(如DBConnectionPool)。外覆类通常作为单例,负责全局的连接管理和配置;内部类则负责具体的连接操作,如获取和释放连接...

    java+mysql+阿里连接池,实现银行操作系统

    总的来说,这个项目是一个典型的Java Web应用,它涵盖了数据库设计、Java编程、数据库连接池使用以及业务逻辑实现等多个IT领域的核心知识。通过实践这样的项目,开发者可以提升自己的综合技能,更好地理解和掌握企业...

    德鲁伊连接池操作文档

    ### 德鲁伊连接池操作文档 #### 一、引言 德鲁伊连接池(Druid)是由阿里巴巴开发的一款高性能、功能丰富的JDBC连接池组件。它不仅提供了数据库连接池的基本功能,还包含了SQL执行监控、Web统计等功能。本文档将...

    基于JDBC的数据库连接池技术研究与应用

    连接池的关键技术包括并发控制和多数据库支持。并发问题通过Java的synchronized关键字来保证线程安全,确保在多线程环境下连接的正确分配和回收。对于多数据库服务器的需求,通常采用单例模式的连接池管理类,根据...

    在线购物程序代码及数据库文件(JDBC连接池+Struts)

    在线购物程序代码及数据库文件(JDBC连接池+Struts)是典型的Web应用程序开发实例,主要涉及了Java Web开发中的核心技术和框架。Struts作为MVC(Model-View-Controller)设计模式的一种实现,用于组织和管理应用的...

    【计算机专业JSP-毕业设计100套之】JSP数据库连接池的研究与实现(源代码+论文)

    本项目名为“JSP数据库连接池的研究与实现”,是一个典型的毕业设计实例,旨在深入理解并实践这一概念。 JSP是一种服务器端的脚本语言,用于创建动态网页。它结合了HTML、Java代码和JavaServer Pages标准标签库,...

    连接池小解

    汤姆凯特连接池是常见的连接池实现之一,虽然JDBC API本身不包含连接池功能,但许多Web应用服务器如Tomcat、WebLogic和WebSphere等都提供了内置的连接池机制。这些连接池通常需要配合特定的服务器API来使用。 连接...

    Java 开发--基于JSP学生成绩管理系统软件的开发(源代码+论文).rar

    8. 性能优化:为了提高系统的响应速度和并发处理能力,可能采用缓存技术、连接池、负载均衡等手段。 9. 文档和源代码:提供的“论文”部分可能包含了系统的设计思路、实现细节、遇到的问题及解决方案,是学习和理解...

    Java开发典型模块大全源代码

    10. **第11章:JDBC数据库操作** - 学习如何使用Java连接和操作数据库,包括连接池管理、SQL查询和事务处理。 11. **第12章:设计模式** - 包含单例、工厂、观察者等常见设计模式的源代码,有助于提高代码质量和可...

    C3P0连接池.zip

    C3P0连接池是一款广泛使用的数据库连接池组件,它为Java应用程序提供了数据库连接的管理与优化。数据库连接池在应用程序中起到复用数据库连接的作用,从而提高系统性能,减少频繁创建和关闭数据库连接带来的开销。C3...

    Java典型应用彻查1000例第四卷:数据库应用基础(源码+PPT+习题).rar

    12. 连接池的配置与管理:理解如何在项目中配置和管理数据库连接池,例如设置最大连接数、超时时间等参数,是每个Java开发者必备的技能。 13. JUnit与Mock测试:在开发过程中,使用JUnit进行单元测试,结合Mockito...

    Java课程设计:ktv点歌系统源码.zip

    - 单例模式:数据库连接池通常使用单例模式,确保全局只有一个实例,节约资源。 8. **事件监听**: - GUI交互:在用户界面中,按钮点击、列表选择等事件需要监听并处理,Java提供了EventListener接口和相关类来...

Global site tag (gtag.js) - Google Analytics