我只希望一个线程同时修改一个策略,不同的策略可以同时修改。 像这样的代码:
private static ConcurrentHashMap<String, InfoCounter> policyNameLockSecond = new ConcurrentHashMap<String, InfoCounter>();
public void registerModiyRequest(String infoName) {
logger.info(" " + Thread.currentThread().getName() + " register :" + infoName);
synchronized (policyNameLockSecond) {
InfoCounter counter = policyNameLockSecond.get(infoName);
if (counter == null) {
counter = new InfoCounter(infoName);
policyNameLockSecond.put(infoName, counter);
}
counter.add();
logger.info(" " + Thread.currentThread().getName() + " counter :" + counter.count());
final long count = counter.getCounter().longValue();
logger.info(" " + Thread.currentThread().getName() + " policyName["
+ infoName + "] count = " + count);
if (count > 1) {
try {
logger.info(" " + Thread.currentThread().getName()
+ " wait ");
counter.getLock().lockInterruptibly();
} catch ( Exception e) {
e.printStackTrace();
logger.error("applyForModifyPolicy, policyNameLock is interrupted");
}
}
}
}
public void unregisterModifyinfoRequest(String infoName) {
logger.info(" " + Thread.currentThread().getName()
+ " unregister policyName: "+infoName);
InfoCounter counter = policyNameLockSecond.get(infoName);
counter.minus();
synchronized (counter) {
try {
final long count = counter.getCounter().longValue();
if (count < 1) {
logger.info(infoName
+ "'s hold count is 1, remove this lock");
policyNameLockSecond.remove(infoName);
} else {
logger.info("still has other thread apply this lock,"
+ count);
}
} catch (Exception e) {
e.printStackTrace();
logger.error("waitAvailableRequestTicket, requestQueueLock is interrupted");
} finally {
logger.info(" "+Thread.currentThread().getName()
+" release this lock");
counter.getLock().unlock();
}
}
}
private static class InfoCounter {
private final String infoName;
private final AtomicLong counter;
private final ReentrantLock lock;
public ReentrantLock getLock() {
return lock;
}
public AtomicLong getCounter() {
return counter;
}
public InfoCounter(final String name) {
this.infoName = name;
this.counter = new AtomicLong();
this.lock = new ReentrantLock();
}
public void add() {
counter.incrementAndGet();
}
public void minus() {
counter.decrementAndGet();
}
public long count(){
return counter.longValue();
}
}
在主函数
中运行代码时public static void main(String[] args) throws Exception {
ExecutorService executor1 = Executors.newFixedThreadPool(20 );
ExecutorService executor2 = Executors.newFixedThreadPool(20 );
for(int i = 0; i < 20 ; i ++){
executor1.submit( new Runnable(){
@Override
public void run(){
try {
configPolicyModifyLock.registerModiyRequest("123");
logger.info(" "+Thread.currentThread().getName() + " register policyName " + "123");
Thread.sleep(300000);
} catch( Exception e ) {
e.printStackTrace();
logger.error(e, e);
} finally {
logger.info(" "+Thread.currentThread().getName() + " unregister 123 ");
configPolicyModifyLock.unregisterModifyinfoRequest("123");
}
}
});
}
for(int i = 0; i < 20 ; i ++){
executor2.submit( new Runnable(){
@Override
public void run(){
try {
configPolicyModifyLock.registerModiyRequest("12");
logger.info(" "+Thread.currentThread().getName() + " register policyName " + "12");
} catch( Exception e ) {
logger.error(e, e);
e.printStackTrace();
} finally {
logger.info(" "+Thread.currentThread().getName() + " unregister 12 ");
configPolicyModifyLock.unregisterModifyinfoRequest("12");
}
}
});
}
}
它可以工作,但是当我在Web应用程序中使用它时,函数抛出IllegalMonitorStateException
。
33387 [http-8088-2] INFO com.platform.util.config.ConfigPolicyModifyLock - http-8088-2 counter :1
2013-10-22 18:31:12,320 33387 [http-8088-2] INFO com.platform.util.config.ConfigPolicyModifyLock - http-8088-2 policyName[12] count = 1
2013-10-22 18:31:12,320 33388 [http-8088-2] INFO com.platform.service.config.impl.ConfigRuleService - start add rule
2013-10-22 18:31:12,321 33389 [http-8088-2] INFO com.platform.service.config.impl.ConfigRuleService - addRule, policyId:228, policyNamepolicy_device_3
2013-10-22 18:31:12,322 33391 [http-8088-2] INFO com.platform.service.config.impl.ConfigRuleService - exist ids:[1, 2]
2013-10-22 18:31:12,324 33392 [http-8088-2] INFO com.platform.service.config.impl.ConfigRuleService - add rule, new rule id:3
2013-10-22 18:31:12,325 33392 [http-8088-2] INFO com.platform.service.config.impl.ConfigRuleService - get rule Id cost :4
2013-10-22 18:31:12,325 33412 [http-8088-2] INFO com.platform.service.config.impl.ConfigDataServiceImpl - batch #1, contain #2 elements
2013-10-22 18:31:12,345 33412 [http-8088-2] INFO com.platform.service.config.impl.ConfigDataServiceImpl - total has #2, separate to #1 batch
2013-10-22 18:31:12,345 33414 [pool-3-thread-3] INFO com.platform.service.config.impl.ConfigDataServiceImpl - cost in MyCallabel is : 1ms, input #2 objects, output #2 objects
2013-10-22 18:31:12,347 33414 [http-8088-2] WARN com.platform.service.config.impl.ConfigDataServiceImpl - moc Type:rule moi size:2 cost time: 2ms
2013-10-22 18:31:12,347 33414 [http-8088-2] INFO com.platform.service.config.impl.ConfigRuleService - check rule name cost:22
2013-10-22 18:31:12,347 33420 [http-8088-2] INFO com.platform.service.config.impl.ConfigRuleService - add rule, moveType = TOP,get first rule: 2, rule's seqno:-1
2013-10-22 18:31:12,353 33420 [http-8088-2] INFO com.platform.service.config.impl.ConfigRuleService - add rule, moveType = TOP,set new rule seqno to -2
2013-10-22 18:31:12,353 33451 [http-8088-2] INFO com.platform.util.PushMessageUtil - push messge to client:{moduleName:policy}{operationType:addRule}{operatorSessionIdAF851447EE69FD42C281AF6650823735}
2013-10-22 18:31:12,384 33453 [http-8088-2] INFO com.platform.infrastructure.db.dao.DbRepositoryHibernateImpl - sql : from NeInfoTable net where net.neId = 3
参数:
2013-10-22 18:31:12,386 33493 [http-8088-2] INFO com.platform.util.PushMessageUtil - push messge to client:{moduleName:config}{operationType:needdownload}{operatorSessionId}
2013-10-22 18:31:12,426 33494 [http-8088-2] INFO com.platform.util.config.ConfigPolicyModifyLock - http-8088-2 unregister policyName: 12
2013-10-22 18:31:12,427 33494 [http-8088-2] INFO com.platform.util.config.ConfigPolicyModifyLock - 12's hold count is 1, remove this lock
2013-10-22 18:31:12,427 33494 [http-8088-2] INFO com.platform.util.config.ConfigPolicyModifyLock - http-8088-2 release this lock
2013-10-22 18:31:12,427java.lang.IllegalMonitorStateException
33497 [http-8088-2] ERROR com.platform.util.aop.listeners.ReturnValueObjExceptionListener - happened exception:class-class com.web.config.ConfigRuleFacade,method-addRule
2013-10-22 18:31:12,430com.common.util.ExceptionMessage
at com.web.config.ConfigRuleFacade.addRule(ConfigRuleFacade.java:99)
at com.web.config.ConfigRuleFacade$$FastClassByCGLIB$$5f74b9c7.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at com.platform.util.aop.interceptors.HsmMethodInterceptor.invoke(HsmMethodInterceptor.java:26)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:50)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:50)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
at com.web.config.ConfigRuleFacade$$EnhancerByCGLIB$$4f0de28e.addRule(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:421)
at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183)
at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1503)
at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:884)
at flex.messaging.endpoints.AbstractEndpoint$$FastClassByCGLIB$$1a3ef066.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.flex.core.MessageInterceptionAdvice.invoke(MessageInterceptionAdvice.java:66)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$FixedChainStaticTargetInterceptor.intercept(Cglib2AopProxy.java:576)
at flex.messaging.endpoints.AMFEndpoint$$EnhancerByCGLIB$$89e2566a.serviceMessage(<generated>)
at flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:121)
at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)
at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:44)
at flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)
at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:146)
at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:278)
at flex.messaging.endpoints.AMFEndpoint$$EnhancerByCGLIB$$89e2566a.service(<generated>)
at org.springframework.flex.servlet.MessageBrokerHandlerAdapter.handle(MessageBrokerHandlerAdapter.java:101)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.listener.HsmUrlFilter.doFilter(HsmUrlFilter.java:69)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
有人能帮助我吗?
感谢。