1

首先一些(非常基本的)示例代码来说明我的问题:

final java.util.concurrent.atomic.AtomicLong previousId = new java.util.concurrent.atomic.AtomicLong();
final com.sun.net.httpserver.HttpServer server = com.sun.net.httpserver.HttpServer.create(new java.net.InetSocketAddress(8666), 0);
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
server.createContext("/", exchange -> {
  final long id = previousId.incrementAndGet();
  System.out.println(String.format("#%s: id attribute=%s", id, exchange.getAttribute("id")));
  exchange.setAttribute("id", id);
  while (true) {
    try {
      Thread.sleep(1_000);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      return;
    }
    System.out.println(String.format("#%s: id attribute=%s", id, exchange.getAttribute("id")));
  }
});
server.start();

在运行这个程序时(在 Java SE 1.8.0_171 上),如果我连续两次请求http://localhost:8666,我会得到以下日志:

#1: id attribute=null
#1: id attribute=1
#1: id attribute=1
#2: id attribute=1
#1: id attribute=2
#2: id attribute=2
#1: id attribute=2
#2: id attribute=2

对于请求 #1,属性最初是null,如预期的那样。但是对于请求 #2,属性是1initial ,这似乎暗示初始值是从另一个请求继承的。更糟糕的是,如您所见,将2请求 #2 的值更改为请求 #1 的值也会更改2。似乎属性在HttpExchange实例之间共享,这不是我所期望的。

我错过了什么还是HttpExchange属性被破坏了?

4

1 回答 1

1

查看源代码,很明显HttpExchange属性是由相同的所有实例共享的HttpContextsetAttribute我发现它具有误导性,尽管getAttribute方法是在HttpExchange. 在我看来,Javadoc也无济于事:

过滤器模块可以使用 HttpExchange 实例存储任意对象作为带外通信机制。

我已经向 net-dev 邮件列表发送了一封电子邮件提交了一个错误。我一有消息就会更新这个答案。

于 2019-12-10T10:44:40.337 回答