Java中Semaphore(信号量) 数据库连接池
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java中Semaphore(信号量) 数据库连接池,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6054字,纯文字阅读大概需要9分钟。
内容图文
![Java中Semaphore(信号量) 数据库连接池](/upload/InfoBanner/zyjiaocheng/487/2f35379dfe3c4d0996f376d58c5b4e39.jpg)
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.util.HashMap;
- import java.util.LinkedList;
- import java.util.Map;
- import java.util.concurrent.Semaphore;
- public class MyConnPool {
- private LinkedList<Connection> unusedConns =
- new LinkedList<Connection>();
- //释放连接时对查找性能要求较高,故使用哈希表
- private Map<Connection,String> usedConns =
- new HashMap<Connection,String>();
- private final Semaphore available;
- public MyConnPool(int size) throws Exception{
- StringBuilder builder = new StringBuilder();
- builder.append("-----pool-----\n");
- available = new Semaphore(size, true);//公平性Semaphore
- String url = "jdbc:mysql://ip:port/name?user=user&password=pwd";
- for(int i = 0 ; i < size ; i++){
- Connection conn = DriverManager.getConnection(url);
- unusedConns.add(conn);
- builder.append("conn-" + i + ":" + conn.hashCode() + "\n");
- }
- builder.append("--------------\n");
- System.out.print(builder.toString());
- }
- public Connection getConn() throws InterruptedException{
- //获取Semaphore中的许可
- available.acquire();
- Connection conn = null;
- synchronized(this){
- conn = unusedConns.removeFirst();
- usedConns.put(conn, "");
- System.out.println(Thread.currentThread().getName()
- + ":" + conn.hashCode() + "[got]");
- System.out.println(display());
- }
- return conn;
- }
- public void close(Connection conn){
- synchronized(this){
- if(usedConns.containsKey(conn)){
- usedConns.remove(conn);
- unusedConns.addLast(conn);
- System.out.println(Thread.currentThread().getName()
- + ":" + conn.hashCode() + "[closed]");
- System.out.println(display());
- }
- }
- //释放线程获取的许可
- available.release();
- }
- private final synchronized String display(){
- String str = "";
- if(unusedConns.size() > 0){
- str = "";
- for(Connection conn : unusedConns){
- str += conn.hashCode() + "|";
- }
- }
- if(!str.equals(""))
- return str;
- else
- return "empty";
- }
- }
- import java.sql.Connection;
- import java.util.concurrent.CountDownLatch;
- public class Test implements Runnable{
- private static CountDownLatch latch
- = new CountDownLatch(1);
- private MyConnPool pool;
- public Test(MyConnPool pool){
- this.pool = pool;
- }
- @Override
- public void run(){
- try {
- latch.await();
- Connection conn = pool.getConn();
- Thread.sleep(1*1000);
- pool.close(conn);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- public static void main(String[] args) throws Exception{
- MyConnPool pool = new MyConnPool(2);
- for(int i = 0 ; i < 4 ; i++){
- Thread t = new Thread(new Test(pool));
- t.start();
- }
- //保证4个线程同时运行
- latch.countDown();
- }
- }
运行结果如下:
[plain] view plain copy- -----pool-----
- conn-0:11631043
- conn-1:14872264
- --------------
- Thread-4:11631043[got]
- 14872264|
- Thread-1:14872264[got]
- empty
- Thread-4:11631043[closed]
- 11631043|
- Thread-2:11631043[got]
- empty
- Thread-1:14872264[closed]
- 14872264|
- Thread-3:14872264[got]
- empty
- Thread-2:11631043[closed]
- 11631043|
- Thread-3:14872264[closed]
- 11631043|14872264|
特别注意如果getConn方法和close方法都为同步方法,将产生死锁:
[java] view plain copy- public synchronized Connection getConn() throws InterruptedException{
- ......
- }
- public synchronized void close(Connection conn){
- ......
- }
同一时刻只能有一个线程调用连接池的getConn方法或close方法,当Semaphore中没有可用的许可,并且此时恰好有一个线程成功调用连接池的getConn方法,则该线程将一直阻塞在acquire方法上,其它线程将没有办法获取连接池上的锁并调用close方法释放许可,程序将会卡死
阻塞方法上不要加锁,否则将导致锁长时间不释放,如果该锁为互斥锁,将导致程序卡住
acquire方法本身使用乐观锁实现,也不需要再加互斥锁
示例二:不可重入互斥锁
[java] view plain copy- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.Semaphore;
- public class Test implements Runnable{
- private static CountDownLatch latch =
- new CountDownLatch(1);
- private static Semaphore lock =
- new Semaphore(1, true);
- @Override
- public void run(){
- try {
- latch.await();
- this.work();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- private void work() throws InterruptedException{
- lock.acquire();
- System.out.println("Locking by "
- + Thread.currentThread().getName());
- Thread.sleep(1*1000);
- lock.release();
- }
- public static void main(String[] args) throws Exception{
- for(int i = 0 ; i < 4 ; i++){
- Thread t = new Thread(new Test());
- t.start();
- }
- //保证4个线程同时运行
- latch.countDown();
- }
- }
运行结果如下:
[plain] view plain copy- Locking by Thread-3
- Locking by Thread-0
- Locking by Thread-1
- Locking by Thread-2
Java中Semaphore(信号量) 数据库连接池
标签:public tco int 方法 else zed url details this
本文系统来源:http://www.cnblogs.com/jiangzhaowei/p/7221208.html
内容总结
以上是互联网集市为您收集整理的Java中Semaphore(信号量) 数据库连接池全部内容,希望文章能够帮你解决Java中Semaphore(信号量) 数据库连接池所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。