如何避免java.util.concurrent.locks.ReentrantLock上的IllegalMonitorStateException $ Sync.tryRelease(ReentrantLock.java:127)

时间:2013-10-22 10:05:31

标签: java multithreading reentrantlock

我只希望一个线程同时修改一个策略,不同的策略可以同时修改。 像这样的代码:

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)

有人能帮助我吗?

感谢。

0 个答案:

没有答案
相关问题