Semaphore学习

Semaphore是一种在多线程环境下使用的设施,该设施负责协调各个线程,以保证它们能够正确、合理的使用公共资源的设施,
也是操作系统中用于控制进程同步互斥的量。Semaphore是一种计数信号量,用于管理一组资源,内部是基于AQS的共享模式。
它相当于给线程规定一个量从而控制允许活动的线程数。

利用Semaphore设计一个链接池。

package com.business.thread.Semaphore;

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
//数据库连接的平庸实现
public class SqlConnectionImpl implements Connection{

    //重写Connection的方法,此处省略    

	//拿一个数据库连接
	public static final Connection fetchConnection() {
		// TODO Auto-generated method stub
		return new SqlConnectionImpl();
	}

}
package com.business.thread.Semaphore;
//一个使用Semaphore实现的数据库连接池

import java.sql.Connection;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;
/*Semaphore是一种在多线程环境下使用的设施,该设施负责协调各个线程,以保证它们能够正确、合理的使用公共资源的设施,
也是操作系统中用于控制进程同步互斥的量。Semaphore是一种计数信号量,用于管理一组资源,内部是基于AQS的共享模式。
它相当于给线程规定一个量从而控制允许活动的线程数。*/

public class DBPoolSemaphore {
	//连接池的大小为10
	private final static int POOL_SIZE = 10;
	//存放连接的容器
	private static LinkedList<Connection> pool = new LinkedList<Connection>();
	//分别表示可用连接和已用连接
	private final Semaphore useFul,useLess;
	
	//初始化线程池
	static {
		for(int i=0;i<POOL_SIZE;i++) {
			pool.addLast(SqlConnectionImpl.fetchConnection());
		}
	}
	/*
	 * Semaphore主要构造方法 
	 * Semaphore(int permits):构造方法,创建具有给定许可数的计数信号量并设置为非公平信号量。
	 * Semaphore(int permits,booleanfair):构造方法,当fair等于true时,创建具有给定许可数的计数信号量并设置为公平信号量。 void
	 * acquire():从此信号量获取一个许可前线程将一直阻塞。相当于一辆车占了一个车位。 void acquire(int
	 * n):从此信号量获取给定数目许可,在提供这些许可前一直将线程阻塞。比如n=2,就相当于一辆车占了两个车位。 void
	 * release():释放一个许可,将其返回给信号量。就如同车开走返回一个车位。 void release(int n):释放n个许可。
	 * int availablePermits():当前可用的许可数。
	 */

	public DBPoolSemaphore(){
		this.useFul = new Semaphore(POOL_SIZE);
		this.useLess = new Semaphore(0);
	}
	//归还连接
	public void returnConnection(Connection connection) throws InterruptedException {
		if(connection!=null) {
			System.out.println("当前有"+useFul.getQueueLength()+"个线程等待数据库连接!"+
		"可用连接数: "+useFul.availablePermits());
			useLess.acquire();
			//对这个池进行加锁
			synchronized (pool) {
				pool.add(connection);
			}			
			useFul.release();
		}
	}
	//从池子拿连接
	public Connection takeConnection() throws InterruptedException {
		useFul.acquire();
		Connection connection;
		synchronized (pool) {
			connection = pool.removeFirst();
		}
		useLess.release();
		
		return connection;
		
	}
	
}

 

package com.business.thread.Semaphore;

import java.sql.Connection;
import java.util.Random;
//测试数据库连接池
public class AppTest {
	private static DBPoolSemaphore dbPool = new DBPoolSemaphore();
	//拿数据库连接的线程
	private static class busiThread extends Thread{
		public void run() {
			Random r = new Random();//让每个线程有个链接时间不一样
			long start = System.currentTimeMillis();
			Connection connection;
			try {
				connection = dbPool.takeConnection();
				System.out.println("Thread_"+Thread.currentThread().getId()+
						"_获取数据库连接共耗时【"+(System.currentTimeMillis()-start)+"】ms");
				Thread.sleep(100+r.nextInt(100));
				System.out.println("查询数据完成,归还连接");
				dbPool.returnConnection(connection);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		}
	}
	
	
	public static void main(String[] args) {
		for(int i = 0;i<50;i++) {
			Thread thread = new busiThread();
			thread.start();
		}
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章