ThreadLocal,LinkedBlockingQueue,线程池 获取数据库连接2改进

Posted llguanli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThreadLocal,LinkedBlockingQueue,线程池 获取数据库连接2改进相关的知识,希望对你有一定的参考价值。

package com.ctl.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import com.ctl.util.ConfigUtils;
import com.ctl.util.LogUtil;

public class ThreadLocalBlockingQueueUtils {
	private static ThreadLocal<LinkedBlockingQueue<Connection>> queueHoder = new ThreadLocal<LinkedBlockingQueue<Connection>>();
	public static int num = 0;
	private static String driver;
	private static String url;
	private static String username;
	private static String password;
	private static int threadPoolMaxNum;

	private static int threadPoolMinNum;
	private static LogUtil log;
	// \u6570\u636E\u5E93\u7C7B\u578Boracle mysql db2
	private static String databasetype;
	public static int getThreadPoolMaxNum() {
		return threadPoolMaxNum;
	}
	
	public static int getThreadPoolMinNum() {
		return threadPoolMinNum;
	}

	public static String getUrl() {
		return url;
	}

	public static String getUsername() {
		return username;
	}

	public static String getPassword() {
		return password;
	}

	static {
		log = new LogUtil();
		databasetype = ConfigUtils.getType("databasetype");
		threadPoolMaxNum = Integer.parseInt(ConfigUtils
				.getType("threadPoolMaxNum"));
		threadPoolMinNum = Integer.parseInt(ConfigUtils
				.getType("threadPoolMinNum"));
		if (databasetype.equals("mysql")) {
			driver = ConfigUtils.getType("mysql.driver");
			url = ConfigUtils.getType("mysql.url");
			username = ConfigUtils.getType("mysql.username");
			password = ConfigUtils.getType("mysql.password");
		} else if (databasetype.equals("oracle")) {
			driver = ConfigUtils.getType("oracle.driver");
			url = ConfigUtils.getType("oracle.url");
			username = ConfigUtils.getType("oracle.username");
			password = ConfigUtils.getType("oracle.password");
		}
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			System.out.println(e.getMessage());
		}
		CreateConnection createConn = new CreateConnection();
		createConn.setDaemon(true);
		createConn.start();
	}

	public static synchronized LinkedBlockingQueue<Connection> getQueue() {
		LinkedBlockingQueue<Connection> queue = queueHoder.get();
		if (queue == null) {
			queue = new LinkedBlockingQueue<Connection>(threadPoolMaxNum);
			queueHoder.set(queue);
			return queue;
		}
		return queue;
	}

	// static void start() {
	// Tom tom = new Tom();
	// tom.start();
	// for(;;){
	// try {
	// Thread.sleep(200);
	// System.out.println("/*************"+getConnection()+"*************/");
	// } catch (InterruptedException e) {
	// }
	// }
	// }
	//
	// public static void main(String[] args) {
	// ThreadLocalBlockingQueueUtils.start();
	// }

	public static Connection getConnection() {
		// System.out.println("进入getConnection");
		class GetConnectionClazz extends Thread {
			LinkedBlockingQueue<Connection> queue = ThreadLocalBlockingQueueUtils
					.getQueue();
			private Connection conn;
			private int queueSize;
			public int getQueueSize() {
				return queueSize;
			}
			public Connection getConn() {
				return conn;
			}
			public synchronized void run() {
				// System.out.println("进入getConnection run()");
				try {
					// System.err.println("-----"+conn+"--------");
					while (conn == null) {// 非常重要没有该while循环当按F5不断刷新时,仅仅要有一个取出来为空后面的全为空
						conn = queue.poll(2, TimeUnit.SECONDS);
					}
					queueSize=queue.size();
					// System.err.println("*******"+conn+"*********");
					// if (conn != null) {
					// System.err.println("\u3010" + queue.size() + "\u3011"
					// + "getConnecion\u6210\u529F\uFF1A" + conn);
					// }
				} catch (InterruptedException e) {
					log.WriteLine("getConnection", e.getMessage());
				}
			}
		}
		GetConnectionClazz jj = new GetConnectionClazz();
		jj.start();
		try {
			jj.join();
		} catch (InterruptedException e) {
			log.WriteLine("getConnection()", e.getMessage());
		}
		log.WriteLine("getConnection()","\u3010" + jj.getQueueSize() + "\u3011"+ "getConnecion\u6210\u529F\uFF1A" + jj.getConn());
		return jj.getConn();
	}

}

// class GG extends Thread {
// public void run() {
// for (;;){
// try {
// ThreadLocalBlockingQueueUtils.getConnection();
// Thread.sleep(300);
// } catch (Exception e) {
// }
// }
// }
// }
/**
 * @descritpion 创建数据库连接的线程类
 * @author Administrator
 * 
 */
class CreateConnection extends Thread {
	LinkedBlockingQueue<Connection> queue = ThreadLocalBlockingQueueUtils
			.getQueue();
	LogUtil log = new LogUtil();

	public synchronized void run() {
		boolean result = false;
		while (true) {
			try {
				Random rand=new Random();
				int num=ThreadLocalBlockingQueueUtils.getThreadPoolMaxNum()-ThreadLocalBlockingQueueUtils.getThreadPoolMinNum();
				int randSize=rand.nextInt(num)+1;
				if(queue.size()>=randSize){
					Thread.sleep(100);
					continue;
				}
				Connection conn = null;
				conn = DriverManager.getConnection(
						ThreadLocalBlockingQueueUtils.getUrl(),
						ThreadLocalBlockingQueueUtils.getUsername(),
						ThreadLocalBlockingQueueUtils.getPassword());
				if (conn != null) {
					result = queue.offer(conn, 1, TimeUnit.SECONDS);
				} else {
					// System.out.println("DriverManager.getConnection is null");
					log.WriteLine("CreateConnection.run()",
							"DriverManager.getConnection()返回 null");
					continue;
				}
				if (result == false) {
					Thread.sleep(100);
					log.WriteLine("CreateConnection.run()",
							"已达到最大连接数queue.size()=" + queue.size());
					// System.out.println("已经满了size=【" + queue.size() + "】");
				} else {
					log.WriteLine("CreateConnection.run()",
							"\u3010" + queue.size() + "\u3011"
									+ "createConnection success:" + conn);
					// System.out.println("\u3010" + queue.size() + "\u3011"
					// + "createConnection success:" + conn);
				}
			} catch (InterruptedException e) {
				// e.printStackTrace();
				log.WriteLine("getConnection", e.getMessage());
				// System.err.println(e.getMessage());
			} catch (SQLException e) {
				log.WriteLine("getConnection", e.getMessage());
				// e.printStackTrace();
				// System.err.println(e.getMessage());
			}
		}
	}
}

以上是关于ThreadLocal,LinkedBlockingQueue,线程池 获取数据库连接2改进的主要内容,如果未能解决你的问题,请参考以下文章

深入剖析ThreadLocal

ThreadLocal(一)设计ThreadLocal的目的

ThreadLocal 的原理讲述 + 基于ThreadLocal实现MVC中的M层的事务控制

对ThreadLocal的一些理解

ThreadLocal源码解析-Java8

ThreadLocal