黑马程序员技术交流社区
标题:
synchronized 和lock 在一起用的时候需要考虑到哪些注意事项?
[打印本页]
作者:
⑷嚸V恱
时间:
2013-8-13 10:12
标题:
synchronized 和lock 在一起用的时候需要考虑到哪些注意事项?
各位童鞋 , 对于locker 和synchronized 一起使用的时候没有想明白,请各位帮住一下。
下面是我 一个 公司写好的 DB连接池的代码.
1.getConnection() 方法中已经用了lock 为什么 getConnection() 方法中还用synchronized ,而revertConnection(Connection conn) 确没有用到
2.ConcurrentLinkedQueue<DBConn> queue 对于 queue 是不是也可以用lock 锁,好比在getConnection()方法 中 用lock 替换synchronized(queue)
3. refreshConnection(Connection conn) 方法中
synchronized(queue){
queue.add(new DBConn(conn));
queue.notify();
}
queue.notify();起到的是什么作用 对于对象queue 没有用到wait 呀
如果问题没有描述清楚,请call
public class ConnectionManager {
private Logger logger = LoggerFactory.getLogger(ConnectionManager.class);
public static final ConnectionManager instance = new ConnectionManager();
private ReentrantLock locker = new ReentrantLock();
private ConnectionPool pool;
private ConnectionManager(){
pool = new ConnectionPool();
}
public static ConnectionManager getInstance(){
return instance;
}
public Connection getConnection(){
locker.lock();
try{
return pool.getConnection();
}finally{
locker.unlock();
}
}
public void revertConnection(Connection conn){
locker.lock();
try{
pool.revertConnection(conn);
}finally{
locker.unlock();
}
}
复制代码
package com.ourgame.clown.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ourgame.clown.ClownData;
import com.ourgame.clown.config.ServerConfig;
public class ConnectionPool {
private Logger logger = LoggerFactory.getLogger(ConnectionPool.class);
private ConcurrentLinkedQueue<DBConn> queue;
private AtomicInteger amount = new AtomicInteger(0);
public ConnectionPool(){
queue = new ConcurrentLinkedQueue<DBConn>();
}
public Connection refreshConnection(Connection conn){
try{
conn.close();
}catch(Exception e){}
return createConnection();
}
public void revertConnection(Connection conn){
if(conn == null){
amount.decrementAndGet();
return;
}
synchronized(queue){
queue.add(new DBConn(conn));
queue.notify();
}
}
public synchronized Connection getConnection(){
//连接只要闲置超过一分半分钟,则抛弃不要了
long time = System.currentTimeMillis();
synchronized(queue){
while(queue.size()>0){
DBConn sl = queue.poll();
if(time - sl.activeTime>90000){
try{
sl.conn.close();
logger.debug("DBManager Close a overtime connection. connection amount="+amount.decrementAndGet()+" queue size="+queue.size());
}catch(Exception e){}
continue;
}else{
logger.debug("DBManager getConnection. connection amount="+amount.get()+" queue size="+queue.size());
return sl.conn;
}
}
}
try{
return createConnection();
}catch(Exception e){
e.printStackTrace(System.err);
return null;
}
}
private synchronized Connection createConnection(){
Connection conn = null;
try{
ServerConfig config = ClownData.getInstance().getServerConfig();
Class.forName(config.getDbDriver());
String url = config.getDbDriverURL();
if(config.getDbMirror() != null && config.getDbMirror().length()>0){
url += ";failover partner="+config.getDbMirror();
}
conn = DriverManager.getConnection(url,
config.getDbUser(),
config.getDbPass());
}catch(Exception e){
logger.debug("Fatal Error create db connection failed.");
}
amount.incrementAndGet();
return conn;
}
class DBConn{
public long activeTime;
public Connection conn;
public DBConn(Connection conn){
this.conn = conn;
this.activeTime = System.currentTimeMillis();
}
}
}
复制代码
作者:
⑷嚸V恱
时间:
2013-8-13 17:24
连飘的都木有, 自己飘一下, 大虾们帮忙解释一下{:soso_e141:}
作者:
神之梦
时间:
2013-8-14 00:20
你的代码,我想说注释太少,看起来很费劲的,而且代码又不是很少的情况下
作者:
⑷嚸V恱
时间:
2013-8-14 07:44
神之梦 发表于 2013-8-14 00:20
你的代码,我想说注释太少,看起来很费劲的,而且代码又不是很少的情况下 ...
版主 这两个代码 可以全部复制。 是个完整的。 如果有什么需要 我会继续粘出代码。
第一步:首先看的是 想获取连接数据库 访问ConnectionManager 类中getConnection()方法 ,这个方法继续访问。ConnectionPool 类中 getConnection() 方法。
1 我不理解的是 在ConnectionManager 类中getConnection()方法里面已经加了lock 锁 ,为什么 在ConnectionPool 类中 getConnection() 方法中 还需要,synchronized 的 。
2,ConnectionPool 类中 getConnection() 方法中对queue 进行了synchronized 是不是可以换成lock
作者:
王靖远
时间:
2013-8-14 20:24
我觉得吧ConnectionManager 中的getConnection()中用不用锁都可以。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2