我一直在想念着你,不管你是否知道~
前阵子,看来一个关于数据库连接池的一个开源项目(miniConnectionPoolManager),之前知道并发情况下,保持同步是一个非常重要的,但是可能是对同步概念的缺失,
并没有如何好地理解以及实践,以至于在看这个连接池的时候,并没有过多关注项目中有关同步的地方,只是稍微注意了下里面的修饰词synchronized以及Semaphore类。直
到被面试官提到数据库连接池中最重要的一个点就是多线程并发的同步问题,由于这个方面的只是确实有缺陷,所以去看了下传智播客多线程的专题,感觉还是不错了。反正晚
上不怎么睡得着,写写记录下。
问题:
当多个线程操作同一个数据的时候,加入都只是读取数据的话,那么并没有问题,而如果这个过程是不仅有读还有写的话,那么问题就会很大。
如同数据库事务并发:
1:丢失更新
2:脏读
3:虚读
4:不可重复读
而在这里我认为,我们在没有对数据库进行操作的时候,所以并没有存在回滚或提交遇到的问题,我们遇到的应该是“读脏数据”这个问题。
解决方案:
加上同步锁;
在java中可以使用的方案:
1:使用修饰词synchronized
这里需要注意的是:不管synchronized针对的是方法还是代码块,它都是有个参照的:
当时方法的时候,这是其实参照的是当前对象this
public synchronized void doSome(){
//...
}
而同步代码块的参照则更具备灵活性,可以一样是this或者是类.class其他等
public void doSome(){
synchronized(参照){
//...
}
}
2:接口Lock(java.util.concurrent.locks)
实现类有:
ReentranLock :这个与修饰词synchronized的作用是一样的
public void doSome(){
lock.lock();
//需要加锁的内容
lock.unlock();
}
ReentranReadWriteLock.ReadLock 读锁,在加了这个锁的情况是允许其他的线程执行读取操作的。
ReentranReadWriteLock.WriteLock 写锁,在加了这个锁的情况,只允许加锁者执行相应的操作,不允许其他线程执行任何的操作、