Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ConcurrentSkipListMap在某些线程中卡住_Java_Multithreading_Concurrency_Deadlock - Fatal编程技术网

Java ConcurrentSkipListMap在某些线程中卡住

Java ConcurrentSkipListMap在某些线程中卡住,java,multithreading,concurrency,deadlock,Java,Multithreading,Concurrency,Deadlock,我有这个容器 private ConcurrentMap<Integer,SortedMap<Long,Object>> users; 有时它工作得很好,但有时(我想是在高负载情况下)某些用户进程方法(所有调用)会被卡住,永远不会输出第2节 如果我交换q.headMap(someNumber).clear()和q.put(obj.someId,obj) 它仍然没有输出第2节 我还尝试了LinkedBlockingQueue而不是ConcurrentSkipListMap

我有这个容器

private ConcurrentMap<Integer,SortedMap<Long,Object>> users;
有时它工作得很好,但有时(我想是在高负载情况下)某些用户进程方法(所有调用)会被卡住,永远不会输出第2节

如果我交换
q.headMap(someNumber).clear()
q.put(obj.someId,obj)
它仍然没有输出第2节

我还尝试了
LinkedBlockingQueue
而不是
ConcurrentSkipListMap
,但我也遇到了同样的问题

它看起来像一个死锁,但我没有在该结构上使用任何同步语句


请分享您的想法,如果您有一个

可能有多个原因;最明显的是不同步的代码。执行线程转储以轻松确定原因

一些问题:

ConcurrentSkipListMap
JavaDocs中,它在
headMap()

因此,如果
obj.someId.compareTo(someNumber)<0
您可以在
put()
处得到一个
IllegalArgumentException
,它在任何地方都不会被处理

这也会导致比赛条件:

q.headMap( someNumber ).clear();
q.put( obj.someId, obj )
如果两个线程具有
(thread1)someNumber=(thread2)obj.someId
,您将得到一个争用条件,谁知道下面会发生什么。此外,正如JavaDocs所说,
clear()
不是一个原子操作


您没有提到您使用
用户
引用对象的另一个地方;
用户是如何填充的。

问题不在于代码被卡住,而在于它抛出异常,异常由ADPool无声处理。我试图通过启用日志功能来推动定制ThreadFactory,但它仍然不起作用。解决方案是为运行时异常提供适当的尝试捕获


所以我学到的教训是,如果您的部分代码没有在线程池中执行,可能是因为RuntimeException,您应该提供更多的try Catch来查找原因

听起来是个愚蠢的想法,但是,您确定您的logger实例是线程安全的吗?可能是记录器实际导致(潜在)死锁吗?尝试将每个日志语句放在同步块中,只是为了调试,看看问题是否消失。它是log4j2。我将尝试发布更新的log4j2。第1部分总是得到输出,并且在“q”上操作后总是会卡住,所以我认为这不是问题,但我会尽力谢谢你,谢谢你,但我没有得到任何异常,所以我们必须假设某个数字是正确的。竞态条件会导致线程安全操作中的死锁吗?@MySqlError不看内部很难说。虽然
clear()
不是原子的说法刚刚在我身上引起了一个启示(我必须亲自检查javadoc)。特别是对于SkipListMap,可能有线程试图在半清除的映射上执行put操作,从而导致数据损坏(或可能的死锁)。但是,您确实说过您尝试了一个
LinkedBlockingQueue
,它确实具有原子清除功能,这表明您的问题可能在其他地方(如果您选择使用SkipListMap,您仍然需要修复竞态条件)。@MySqlError但是您如何知道您有死锁?你有没有接受线程转储?回答您的问题:我不这么认为(我相信JDK类构建得足够好,不会死锁,但这取决于内部实现)。还有,您如何确定没有异常?它不会出现在日志中,除非你得到
Future
treat它(你的代码没有)。请参阅此处了解更多详细信息-您是对的,它不应该是死锁,因为如果它是死锁,那么它应该使整个线程池死锁,在我的示例中,该线程池只有8个线程。所以,如果运行时异常发生在线程池中,它将是静默的?如果是这样,我想这可能是我正在处理的一个问题
executorService.execute(new Runnable() {
            @Override
            public void run() {
                process(obj);
            }
        });
The returned map will throw an IllegalArgumentException on an attempt to insert a key outside its range.
q.headMap( someNumber ).clear();
q.put( obj.someId, obj )