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

线程从中获取资源时处于等待状态

洪琦
2023-03-14

我用绝地武士连接redis服务器。Redis ip值在一个单独的文件中配置,我试图在初始化期间加载该文件

private static JedisPool pool;

public static void initRedisClient() throws Exception {
   String redisConfigPath = "/conf/redis.properties";
   Properties docsRedisProp = RedisUtils.loadProperties(redisConfigPath);
   pool = new JedisPool(docsRedisProp.getProperty("redisserver"));    
   }
}

我从redis获取多个密钥的mget方法如下

public static List<String> mgetDataFromRedisCache(String[] keys) throws CacheException {
        Jedis jedisCon = null; 
        try {
            jedisCon = getJedis();
            jedisCon.select(1);
            return jedisCon.mget(keys);
        } catch (Exception e) {
            LOGGER.warning("Exception while fetching data from Redis Client. EXCEPTION=" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (jedisCon != null) {
                returnJedis(jedisCon);
            }
        }
        return null;
    }

当我在属性文件中给出了不正确的ip值时,访问它的请求线程等待了很长一段时间。我的请求不应该因为池中资源不可用而停止。

在这里,我附加了停顿线程的线程转储(即;处于等待状态的线程)

###_http-nio-8443-exec-140" #104908 daemon prio=5 os_prio=0 tid=0x00007f247805f000 nid=0x4266 waiting on condition [0x00007f220a4df000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000006fe438408> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at org.apache.commons.pool2.impl.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:524)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:438)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361)
    at redis.clients.util.Pool.getResource(Pool.java:40)
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:84)
    at com.retail.store.RedisClient.getJedis(RedisClient.java:53)
    at com.retail.store.RedisClient.mgetDataFromRedisCache(RedisClient.java:82)

我怎样才能做到这一点?非常感谢您的帮助。提前感谢:-)

共有2个答案

刘玉石
2023-03-14

您可以使用适当的构造函数创建具有短超时的jedis连接。

Jedis jedisCon = public Jedis(String host, int port, int timeout);
蒯翰墨
2023-03-14

redis服务器ip维护在一个属性文件中,并在运行时加载它。

属性文件包含默认ip。但是,当我在开发设置中部署相同的组件时,redis ip应该已经更改了,但我没有这样做。我的开发安装程序无法连接到给定的ip。

Jedis具有以下默认配置

最大活动连接数=8

读取超时=2000

最大活动连接数是池可以同时保持的最大活动连接数。

读取超时是建立连接并准备通过建立的连接接收数据时设置的最长时间(毫秒)。

在我们的例子中,连接没有建立(对于前8个线程),并且它从未被杀死——连接是没有为这些连接设置超时。使get调用redis的其他线程现在转到parkWAIT状态。

通过设置以下池配置(即设置建立连接的最大等待时间),我们可以避免线程进入延长等待状态

JedisPoolConfig jedisConfig = new JedisPoolConfig();
jedisConfig.setMaxWaitMillis(maxWaitInMillis);
 类似资料:
  • 我们在其中一个模块中使用了Hystrix-断路器模式[library]。usecase是:-我们正在从kafka轮询16个消息,并使用pararllel流处理它们,因此,对于工作流中的每条消息,它需要3个rest调用,这些调用由hystric命令保护。现在,问题是当我尝试运行单个实例时,CPU显示尖峰,线程转储显示许多线程处于等待状态,等待所有3个命令。如下所示:-

  • 用例:每次我需要处理一个作业时创建一个新线程。 目前的实现:我使用的执行器服务与固定大小的线程池,例如50。对于每个作业,我都向executor服务提交一个新线程。 我试图实现的行为更像是自动伸缩。在高峰时间跨越更多的服务器(在本例中是线程)。并在负载不是很高的时候终止额外的服务器并保持最小的服务器计数。

  • 问题内容: 我的问题: 当线程处于状态(非休眠)> 99.9%的时间时,JVM中的大量线程是否会消耗大量资源(内存,CPU)吗?当线程正在等待时,如果根本需要维护它们,需要花费多少CPU开销? 答案是否也适用于与非JVM相关的环境(例如linux内核)? 内容: 我的程序收到大量占用空间的程序包。它在不同的程序包中存储相似属性的计数。在收到包裹后的给定时间(可能是数小时或数天)之后,该特定包裹将过

  • 我还发现这个帖子在sun.misc.unsafe.park(本地方法)等待,但它对我的情况没有帮助。 在这种情况下,我还可以调查什么来获得更多细节?

  • “catalina-exec-681”守护进程prio=10 tid=0x00007f530442c800 nid=0x16f7在条件[0x00007f51b9a7b000]java.lang.thread.state:waiting(parking)在sun.misc.unsafe.park(本机方法)-在java.util.concurrent.locks.locks.locks.slocks

  • 我只想使用notify方法恢复所有进入等待状态的线程。我不想使用notifyAll()恢复所有处于等待状态的线程。 调用 wait() 将释放内部锁,以便队列中的其他线程可以获取它。我希望最后一个线程直接调用 notify(),这将通知任何处于等待状态的线程再次恢复。等待线程唤醒并调用 notify(),这将再次恢复处于等待状态的线程。