2024 年 Clojure 状况调查! 中分享你的想法。

欢迎!请参阅 关于 页面以获取有关此工作的一些更多信息。

0 投票
编译器
已关闭

看起来 Java 系统属性的迭代版本不是线程安全的。可以使用以下代码进行确认

import java.io.FileWriter;
import java.util.Map;
import java.util.Properties;
import java.util.Random;

public class JavaPropertiesTest {
  public static void main(String[] args) throws Exception {
    new Thread(() -> {
      while (true) {
        Properties properties = System.getProperties();
        try (FileWriter fileOutputWriter = new FileWriter("/dev/null")){
          for (Map.Entry<Object, Object> entry : properties.entrySet()) {
            fileOutputWriter.append(entry.getKey().toString());
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }).start();

    new Thread(() -> {
      Random gen = new Random();
      while (true) {
        System.getProperties().setProperty(Integer.toString(gen.nextInt()), Integer.toString(gen.nextInt()));
      }
    }).start();
  }
}

在 clojure 1.8.x 版本中的堆栈跟踪,最新版本也是相同的
原因:java.util.ConcurrentModificationException 在 java.util.Hashtable$Enumerator.next(Hashtable.java:1387) 处抛出,在 clojure.lang.RT$4.invoke(RT.java:509) 处引发,在 clojure.lang.LazySeq.sval(LazySeq.java:40) 处引发,在 clojure.lang.LazySeq.seq(LazySeq.java:49) 处引发,在 clojure.lang.ChunkedCons.chunkedNext(ChunkedCons.java:59) 处引发,在 clojure.lang.ChunkedCons.next(ChunkedCons.java:43) 处引发,在 clojure.lang.RT.next(RT.java:688) 处引发,在 clojure.core$next4341.invokeStatic(core.clj:64) 处引发,在 clojure.core.protocols$naive_seq_reduce.invokeStatic(protocols.clj:63) 处引发,在 clojure.core.protocols$interface_or_naive_reduce.invokeStatic(protocols.clj:72) 处引发,在 clojure.core.protocols$fn6755.invokeStatic(protocols.clj:168) 处引发,在 clojure.core.protocols$fn6755.invoke(protocols.clj:124) 处引发,在 clojure.core.protocols$fn6755$G6705__6719.invoke(protocols.clj:19) 处引发,在 clojure.core.protocols$seq_reduce.invokeStatic(protocols.clj:31) 处引发,在 clojure.core.protocols$fn6732.invokeStatic(protocols.clj:75) 处引发,在 clojure.core.protocols$fn6732.invoke(protocols.clj:75) 处引发,在 clojure.core.protocols$fn6684$G66796697.invoke(protocols.clj:13) 处引发,在 clojure.core$reduce.invokeStatic(core.clj:6545) 处引发,在 clojure.core.server$parse_props.invokeStatic(server.clj:143) 处引发,在 clojure.core.server$start_servers.invokeStatic(server.clj:154) 处引发,在 clojure.core.server$start_servers.invoke(server.clj:154) 处引发,在 clojure.lang.Var.invoke(Var.java:379) 处引发,在 clojure.lang.RT.doInit(RT.java:482) 处引发。

已关闭,备注: Clojure 1.12.0-alpha4 已修复

2 个回答

0 投票

您是否在Clojure启动过程中以某种方式看到这个情况?

这位于Clojure启动时单个线程中调用,因此我不确定这究竟是如何发生的。哪个线程在修改props属性?

by
是的,这在我的使用clojure作为组件的EMR作业中确实发生了。我不知道在这种情况下其他线程实际上在做什么,但看起来它可能与EMRFS(s3客户端)的设置有关。不幸的是,由于编辑器限制,我无法在这里粘贴所有堆栈跟踪。
0 投票
by
...