当前位置: 首页 > 知识库问答 >
问题:

当我把jedis放在线程本地时,它不能成功关闭

葛飞扬
2023-03-14

我只想在一个线程中保存一个绝地实例,所以我编写了一个引用HibernateSessionFactory的类。

public class JedisFactory {

private static final ThreadLocal<Jedis> threadLocal = new ThreadLocal<Jedis>();
private static JedisPool pool;

static {
    try {
        Long timestampPre = System.currentTimeMillis();
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxWaitMillis(Constants.REDIS_MAX_WAIT_MILLIS);
        config.setMinIdle(Constants.REDIS_MIN_IDLE);
        config.setMaxIdle(Constants.REDIS_MAX_IDLE);
        config.setMaxTotal(Constants.REDIS_MAX_ACTIVE);
        pool = new JedisPool(config, Constants.REDIS_ADDRESS, Constants.REDIS_PORT, Constants.REDIS_TIMEOUT);
        System.out.println("TEST createJedisPool: " + (System.currentTimeMillis() - timestampPre));
    } catch (Exception e) {
        System.err.println("%%%% Error Creating JedisFactory %%%%");
        e.printStackTrace();
    }
}

private JedisFactory() {
}

public static Jedis getJedis() throws JedisConnectionException {
    Jedis jedis = (Jedis) threadLocal.get();

    if (jedis == null) {
        if (pool == null) {
            rebuildJedisPool();
        }
        jedis = (pool != null)
                ? pool.getResource()
                : null;

        if (jedis != null) jedis.auth(Constants.REDIS_AUTH);
        threadLocal.set(jedis);
    }

    if (!jedis.isConnected()) {
        System.out.println(System.currentTimeMillis() + "open jedis");
        jedis.connect();
    }

    return jedis;
}

/**
 *  Rebuild jedis factory
 *
 */
public static void rebuildJedisPool() {
    try {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxWaitMillis(Constants.REDIS_MAX_WAIT_MILLIS);
        config.setMinIdle(Constants.REDIS_MIN_IDLE);
        config.setMaxIdle(Constants.REDIS_MAX_IDLE);
        config.setMaxTotal(Constants.REDIS_MAX_ACTIVE);
        // 创建连接池
        pool = new JedisPool(config, Constants.REDIS_ADDRESS, Constants.REDIS_PORT, Constants.REDIS_TIMEOUT);
    } catch (Exception e) {
        System.err.println("%%%% Error Creating JedisFactory %%%%");
        e.printStackTrace();
    }
}

/**
 *  Close the single jedis instance.
 *
 */
public static void closeJedis() {
    Jedis jedis = (Jedis) threadLocal.get();
    threadLocal.set(null);

    if (jedis != null) {
        jedis.close();
    }
}
}

它确实将一个绝地实例保存在一个线程中并正常工作,但当我想通过调用closeJedis()来克隆绝地时,它会抛出异常。以下是异常信息:

[详细信息]redis。客户。绝地武士。例外。JedisException:无法将资源返回到redis的池中。客户。绝地武士。绝地线轴。redis上的returnResource(JedisPool.java:114)。客户。绝地武士。绝地线轴。redis上的returnResource(JedisPool.java:1)。客户。绝地武士。绝地武士。在com上关闭(Jedis.java:3306)。凌霞。越州。数据隐藏物AdCacheImpl。getAdByCity(AdCacheImpl.java:87)位于com。凌霞。越州。数据服务AdServiceImpl。getAdByCity(AdServiceImpl.java:172)位于com。凌霞。越州。应用程序。控制器。AdController。getBanner(AdController.java:50)在sun。反映NativeMethodAccessorImpl。在sun上调用0(本机方法)。反映NativeMethodAccessorImpl。在sun上调用(NativeMethodAccessorImpl.java:62)。反映DelegatingMethodAccessorImpl。在java上调用(DelegatingMethodAccessorImpl.java:43)。朗,反思一下。方法在org上调用(Method.java:483)。springframework。网状物绑定注释。支持HandlerMethodInvoker。org上的invokeHandlerMethod(HandlerMethodInvoker.java:175)。springframework。网状物servlet。mvc。注释。注释方法HandlerAdapter。org上的invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:446)。springframework。网状物servlet。mvc。注释。注释方法HandlerAdapter。handle(AnnotationMethodHandlerAdapter.java:434)位于org。springframework。网状物servlet。调度员服务。doDispatch(DispatcherServlet.java:943)位于org。springframework。网状物servlet。调度员服务。doService(DispatcherServlet.java:877)位于org。springframework。网状物servlet。FrameworkServlet。processRequest(FrameworkServlet.java:961)位于org。springframework。网状物servlet。FrameworkServlet。javax上的doGet(FrameworkServlet.java:852)。servlet。http。HttpServlet。服务(HttpServlet.java:618)位于org。springframework。网状物servlet。FrameworkServlet。javax上的服务(FrameworkServlet.java:837)。servlet。http。HttpServlet。服务(HttpServlet.java:725)位于org。阿帕奇。卡塔琳娜。果心应用过滤链。org上的internalDoFilter(ApplicationFilterChain.java:291)。阿帕奇。卡塔琳娜。果心应用过滤链。doFilter(ApplicationFilterChain.java:206)位于org。阿帕奇。公猫websocket。服务器WsFilter。doFilter(WsFilter.java:52)位于org。阿帕奇。卡塔琳娜。果心应用过滤链。org上的internalDoFilter(ApplicationFilterChain.java:239)。阿帕奇。卡塔琳娜。果心应用过滤链。doFilter(ApplicationFilterChain.java:206)位于org。阿帕奇。卡塔琳娜。果心标准包装阀。在org上调用(StandardWrapperValve.java:219)。阿帕奇。卡塔琳娜。果心标准连接阀。在org上调用(StandardContextValve.java:106)。阿帕奇。卡塔琳娜。验证者。AuthenticatorBase。在org上调用(AuthenticatorBase.java:501)。阿帕奇。卡塔琳娜。果心标准阀门。在org上调用(StandardHostValve.java:142)。阿帕奇。卡塔琳娜。阀门。打开阀门。在org上调用(ErrorReportValve.java:79)。阿帕奇。卡塔琳娜。阀门。抽象逻辑阀。在org上调用(AbstractAccessLogValve.java:610)。阿帕奇。卡塔琳娜。果心标准引擎版本。在org上调用(StandardEngineValve.java:88)。阿帕奇。卡塔琳娜。连接器。郊狼适应者。服务(CoyoteAdapter.java:537)位于org。阿帕奇。郊狼。http11。抽象Http11处理器。org上的进程(AbstractHttp11Processor.java:1085)。阿帕奇。郊狼。AbstractProtocol$AbstractConnectionHandler。org上的进程(AbstractProtocol.java:658)。阿帕奇。郊狼。http11。Http11aProtocol$Http11ConnectionHandler。进程(Http11AprProtocol.java:277)位于org。阿帕奇。公猫util。网APR$SocketProcessor。doRun(aprenpoint.java:2407)位于org。阿帕奇。公猫util。网APR$SocketProcessor。在java上运行(aprenpoint.java:2396)。util。同时发生的线程池执行器。java上的runWorker(ThreadPoolExecutor.java:1142)。util。同时发生的ThreadPoolExecutor$Worker。在org上运行(ThreadPoolExecutor.java:617)。阿帕奇。公猫util。线程。TaskThread$wrappingranable。在java上运行(TaskThread.java:61)。朗。丝线。运行(Thread.java:745)的原因是:redis。客户。绝地武士。例外。JedisException:无法将资源返回到redis的池中。客户。util。水塘redis上的returnResourceObject(Pool.java:61)。客户。绝地武士。绝地线轴。returnResource(JedisPool.java:111)。。。还有41个原因:java。lang.IllegalStateException:对象已被转发到此池或在组织中无效。阿帕奇。平民池2。impl。通用对象池。redis上的returnObject(generiObjectPool.java:582)。客户。util。水塘returnResourceObject(Pool.java:59)。。。还有42个

共有1个答案

曾新立
2023-03-14

首先,Jedis.close()在实例未合并实例时断开连接,并在实例合并时将实例返回到池。

如果您将绝地武士与try with资源一起使用,在try语句结束时,您的绝地武士实例将返回池中。所以,当您调用close()显式地将实例返回到池时,池会抱怨该实例返回了两次。

到目前为止,如果您试图自己管理池化实例,则不应该将Jedis实例与try-with资源一起使用。

 类似资料:
  • 当我运行以下代码时,我的应用程序崩溃: 这是我的Logcat输出: 03-26 12:35:16.900: E/AndroidRuntime(30127): FATAL EXCEPTION: main 03-26 12:35:16.900: E/AndroidRuntime(30127):java.lang.RuntimeException:无法启动活动ComponentInfo{nl.appon

  • Android Studio给了我一个弯弯曲曲的说法,我应该/可以把它变成一个lambda。我刚回到我的Android系统。 这是弯曲的“对象:PopupMenu.OnMenuItemClickListener”

  • 我正试图从图中的窗体向表插入子层,但为什么不能使用where呢?

  • 静态编程语言中的属性和开放属性有什么区别?下面的代码抱怨我声明setter私有,Intellij说开放属性不允许私有setter。什么是开放属性? 为什么上面的代码无效,而这个代码有效? 编辑:我使用的是spring-allopen插件,将类显式标记为open并没有什么不同。

  • 当我尝试播放我的音乐时,Discord机器人不会播放音乐。它使用ytdl核心和ffmpeg。我的代码是: 每当我尝试播放歌曲时,都会发生以下错误: (节点:5180)未处理的PromisejectionWarning:错误:找不到FFmpeg/avconv!在功能上。getInfo(C:\Users\picar\Desktop\DiscordMusicBot\node\u modules\pris

  • 校验者: @片刻 翻译者: @X 模型管道化 我们已经知道一些模型可以做数据转换,一些模型可以用来预测变量。我们可以建立一个组合模型同时完成以上工作: import numpy as np import matplotlib.pyplot as plt from sklearn import linear_model, decomposition, datasets from sklearn.p