spring 睡眠线程被中断,导致与数据库的连接丢失

8yparm6h  于 2023-06-21  发布在  Spring
关注(0)|答案(4)|浏览(192)

我是JAVA中多线程的新手,遇到了一个问题。我得到一个异常,它说
java.lang.InterruptedException:睡眠中断
这是在丢失到DB的连接之后发生的。我不知道那里出了什么问题。看起来线程被中断后,它们正在重新初始化,但没有开始。
下面是我的run方法

public void run() {
        LOG.info("Started");
        running = true;
        while (running) {
            Lock readLock = readWriteLock.readLock();
            readLock.lock();
            long loopDelay;
            try {
                loopDelay = executor.execute();
                if (loopDelay > 0) {
                    Thread.sleep(loopDelay);
                }
            } catch (Exception e) {
                LOG.info("Executor Interrupted", e);
                break;
            } finally {
                readLock.unlock();
            }
        }
        LOG.info("Stopped");
    }

**可能的解决方案:在浏览了大卫建议的链接后,我觉得这里的问题与David提到的相同,即“线程在睡眠时无法处理中断。”**所以为了解决这个问题,我应该以更好的方式处理中断异常,即David的建议。

下面是我的堆栈跟踪。有人能帮助我理解这个问题吗

2012-02-03 10:38:09,260   150696427 [taskDiscoveryCallExecutorThread] INFO  (TaskExecutorThread.java:89) - Executor Interrupted
    java.lang.InterruptedException: sleep interrupted
        at java.lang.Thread.sleep(Native Method)
        at com.xyz.abc.backgroundtask.impl.TaskExecutorThread.run(TaskExecutorThread.java:86)
    2012-02-03 10:38:09,261   150696428 [taskDiscoveryCallExecutorThread] INFO  (TaskExecutorThread.java:95) - Stopped
    2012-02-03 10:38:09,261   150696428 [main] INFO  (TaskExecutorThread.java:69) - shutdown
    2012-02-03 10:38:09,262   150696429 [taskRuleExecutorThread] ERROR (JDBCExceptionReporter.java:101) - Cannot get a connection, general error
    2012-02-03 10:38:09,262   150696429 [taskRuleExecutorThread] ERROR (JDBCExceptionReporter.java:101) - Cannot get a connection, general error
    2012-02-03 10:38:09,294   150696461 [taskRuleExecutorThread] DEBUG (EventScope.java:107) - Destroy scope for customer c02c5ac7-8dee-42aa-b344-ff7f7f6894f5
    2012-02-03 10:38:09,294   150696461 [taskRuleExecutorThread] ERROR (TaskExecutor.java:205) - Catch exception
    org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: Cannot open connection; uncategorized SQLException for SQL [???]; SQL state [null]; error code [0]; Cannot get a connection, general error; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, general error
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.orm.hibernate3.HibernateAccessor.convertJdbcAccessException(HibernateAccessor.java:424)
        at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:410)
        at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
        at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
        at org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:1046)
        at org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:1039)
        at com.xyz.abc.web.dao.RuleDao.loadActive(RuleDao.java:53)
        at com.xyz.abc.web.service.RuleServiceImpl.createRulesByTemplate(RuleServiceImpl.java:39)
        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 org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy60.createRulesByTemplate(Unknown Source)
        at com.xyz.abc.rules.RulesInvoker.checkIsInitialized(RulesInvoker.java:97)
        at com.xyz.abc.rules.RulesInvoker.invokeForEvent(RulesInvoker.java:73)
        at com.xyz.abc.mdp.RabbitMqMessageProcessor.processMessage(RabbitMqMessageProcessor.java:53)
        at sun.reflect.GeneratedMethodAccessor101.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:186)
        at com.xyz.abc.backgroundtask.impl.TaskExecutor.invokeMethod(TaskExecutor.java:156)
        at com.xyz.abc.backgroundtask.impl.TaskExecutor.invokeBean(TaskExecutor.java:139)
        at com.xyz.abc.backgroundtask.impl.TaskExecutor.doExecute(TaskExecutor.java:116)
        at com.xyz.abc.backgroundtask.impl.TaskExecutor.executeTask(TaskExecutor.java:104)
        at com.xyz.abc.backgroundtask.impl.TaskExecutor.access$200(TaskExecutor.java:39)
        at com.xyz.abc.backgroundtask.impl.TaskExecutor$1.doInTransaction(TaskExecutor.java:85)
        at com.xyz.abc.backgroundtask.impl.TaskExecutor$1.doInTransaction(TaskExecutor.java:79)
        at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
        at com.xyz.abc.backgroundtask.impl.TaskExecutor.execute(TaskExecutor.java:79)
        at com.xyz.abc.backgroundtask.impl.TaskExecutorThread.run(TaskExecutorThread.java:84)
    Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, general error
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:118)
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
        at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
        at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
        at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
        at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:161)
        at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1596)
        at org.hibernate.loader.Loader.doQuery(Loader.java:717)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
        at org.hibernate.loader.Loader.doList(Loader.java:2294)
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2172)
        at org.hibernate.loader.Loader.list(Loader.java:2167)
        at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
        at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1706)
        at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
        at org.springframework.orm.hibernate3.HibernateTemplate$36.doInHibernate(HibernateTemplate.java:1056)
        at org.springframework.orm.hibernate3.HibernateTemplate$36.doInHibernate(HibernateTemplate.java:1)
        at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
        ... 33 more
    Caused by: java.lang.InterruptedException
        at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:485)
        at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1104)
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
        ... 50 more
    2012-02-03 10:38:09,399   150696566 [taskRuleExecutorThread] INFO  (TaskExecutor.java:93) - org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
2012-02-03 10:38:09,399   150696566 [taskRuleExecutorThread] INFO  (TaskExecutorThread.java:89) - Executor Interrupted
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at com.xyz.abc.backgroundtask.impl.TaskExecutorThread.run(TaskExecutorThread.java:86)
2012-02-03 10:38:09,399   150696566 [taskRuleExecutorThread] INFO  (TaskExecutorThread.java:95) - Stopped
2012-02-03 10:38:09,400   150696567 [main] INFO  (TaskExecutorThread.java:69) - shutdown
2012-02-03 10:38:09,400   150696567 [taskParatureExecutorThread] INFO  (TaskExecutorThread.java:89) - Executor Interrupted
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at com.xyz.abc.backgroundtask.impl.TaskExecutorThread.run(TaskExecutorThread.java:86)
2012-02-03 10:38:09,400   150696567 [taskParatureExecutorThread] INFO  

(TaskExecutorThread.java:95) - Stopped
2012-02-03 10:38:09,400   150696567 [main] INFO  (TaskExecutorThread.java:69) - shutdown
9o685dep

9o685dep1#

线程在睡眠时不能处理中断。因此,您需要在线程从睡眠中出来时捕获异常,然后处理中断。在this answer中很好地解释了该方法。通常它看起来像这样:

try
  {
      Thread.sleep(whatever);
  }
  catch (InterruptedException e)
  {
       Thread.currentThread().interrupt(); // restore interrupted status
  }
qxgroojn

qxgroojn2#

你是否在代码中的某个地方抛出了一个被中断的异常,可能是为了发出一个线程应该停止的信号?你能提供这个方法的代码吗:

com.xyz.abc.backgroundtask.impl.TaskExecutorThread.run
nxowjjhe

nxowjjhe3#

让我们用你的代码来理解:

while (true) {
  // Your logic code
}

它有什么作用?没什么,它只是无休止地旋转CPU。我们能终止它吗?在Java中不是。只有当整个JVM停止时,当您按下Ctrl-C时,它才会停止。在Java中,除非线程自己退出,否则没有办法终止线程。这是我们必须牢记的原则,其他的一切都是显而易见的。
那么,当我们需要停止线程时,我们如何停止它?
下面是它在Java中的设计。每个线程中都有一个标志,我们可以从外部设置。线程可能会偶尔检查它并停止它的执行。自愿!具体操作如下:

Thread loop = new Thread(
  new Runnable() {
    @Override
    public void run() {
      while (true) {
        if (Thread.interrupted()) {
          break;
        }
        // Your logic code
      }
    }
  }
);
loop.start();
uwopmtnx

uwopmtnx4#

您可以检查h2数据库锁定文件是否在服务器关闭后仍然存在。文件名为<keycloak_dir>/data/h2/keycloakdb.lock.db
删除文件并启动服务器。

相关问题