并发库学习笔记四

ConcurrentHashMap并没有实现Lock-Free,只是使用了分离锁的办法使得能够支持多个writer开发,但是他需要更多的内存同样的思路用于更新数据库----乐观锁

publicclassSequenceDao{

publicbooleancompareAndSet(Stringname,intvalue,intexpect){

Map<String,Object>parameters=newHashMap<String,Object>();

parameters.put("name",name);

parameters.put("value",value);

parameters.put("expect",expect);

 

intupdateCount=getSqlMapClientTemplate().update("seauence.compareAndSet",parameters);

returnupdateCount==1;

}

}

 

publicclassSequenceService{

 

@Transactional(propagation=propagation.NOT_SUPPORTED)

publicsynchronizedvoidintcrement(StringsequenceName){

for(;;){

intvalue=dao.getValue(sequenceName);

if(dao.compareAndSet(sequenceName,value+1,value)){

break;

}

}

}

}

 

 

使用悲观锁版本

publicclassSepuenceService{

SequenceDaodao=newSequenceDao();

 

@Transactional(propagation=Propagation.REQUIRED)

publicsynchronizedvoidincrement(StringsequenceName){

intvalue=dao.getValueForUpdate(sequenceName);

dao.set(sequenceName,value+1);

 

}

}

 

 

publicclassSepuenceService{

SequenceDaodao=newSequenceDao();

 

@Transactional(propagation=Propagation.REQUIRED)

publicsynchronizedvoidincrement(StringsequenceName){

intvalue=dao.getValueForUpdate(sequenceName);

dao.set(sequenceName,value+1);

 

}

}

 

 

注:lock-free算法可以说是乐观锁,如果非激烈竟争的时候,不公使用锁

 

 

 

CopyOnWriteArrayList

publicclassEngLine{

privateList<Listener>listeners=newArrayList<Listener>();

 

publicbooleanaddListener(Listenerlistener){

synchronized(listener){

returnlisteners.add(listener);

}

}

 

publicvoiddoxxx(){

synchronized(listeners){

for(Listenerlistener:listeners){

listener.hashCode();

}

}

}

}

 

 

publicclassEngLine2{

//能够提高读操作时的效率

privateList<Listener>listeners=newCopyOnWriteArrayList<Listener>();

 

publicbooleanaddListener(Listenerlistener){

synchronized(listener){

returnlisteners.add(listener);

}

}

 

publicvoiddoxxx(){

synchronized(listeners){

for(Listenerlistener:listeners){

listener.hashCode();

}

}

}

}

 

锁的使用

1使用支持CAS的数据结构,如:

ActionXXXConcurrentMapCopyOnWriteListConcurretLinkedQueue

2一定要使用锁的时候,注意锁的顺序,相反顺序获得锁,就容易产生死锁

3死锁经常是无法避免的,鸵鸟策略很多基础框架都采用

4通过Dump线程的StackTrace,例如linux下执行kill-3<pid>

或者jstack-l<pid>

或者使用jconsole连接上去查看线程的StackTrace

5外部锁常被忽视,例如数据库的锁

你可能感兴趣的:(学习笔记)