Java 将静态字段传递给线程

Java 将静态字段传递给线程,java,multithreading,static,final,Java,Multithreading,Static,Final,我用Java编写了一个小型HTTP服务器,在将静态变量(服务器配置:端口、根等)传递到处理请求的线程时遇到问题。我不希望我的线程修改这些变量,如果它扩展了服务器类,它也将继承我不希望的方法 出于性能原因,我不想使用getter。如果我将静态成员设为final,那么从配置文件加载它们的值时就会出现问题 这里有一个例子 class HTTPServer { static int port; static File root; etc.. .... //must be public public v

我用Java编写了一个小型HTTP服务器,在将静态变量(服务器配置:端口、根等)传递到处理请求的线程时遇到问题。我不希望我的线程修改这些变量,如果它扩展了服务器类,它也将继承我不希望的方法

出于性能原因,我不想使用getter。如果我将静态成员设为final,那么从配置文件加载它们的值时就会出现问题

这里有一个例子

class HTTPServer {
static int port; 
static File root;
etc..
....
//must be public
public void launch() throws HTTPServerException {
    loadConfig();
    while (!pool.isShutdown()) {
            ....
        //using some config here
             ...
        try {
    Socket s = ss.accept();
    Worker w = new Worker(s);
    pool.execute(w);
        }catch () {...}
    }
}
private void loadConfig(){ //reading from file};
...
other methods that must be public goes here
}
我也不想将worker作为嵌套类。它在另一个包裹里


您的建议是什么?

将静态数据读入一个静态“sharedConfig”对象,该对象也有一个套接字字段-您可以将该字段用于侦听套接字。当acccpet()返回服务器客户端套接字时,克隆()sharedConfig,插入新套接字并将该对象传递给服务器客户端工作线程。然后,线程将获得一个配置副本,它可以在不影响任何其他线程或静态配置的情况下对其进行erad甚至修改

你可以把你的配置放在期末考试中。然后,您的工作人员可以引用它,并以线程安全的方式更新它

比如:

class HTTPServer {
  public static final AtomicReference<ServerConf> config = 
    new AtomicReference(new ServerConf());
}
Worker w = new Worker(s, HTTPServer.config.get());
HTTPServer.config.set(new ServerConf(8080, new File("/foo/bar"));
然后,您的工作人员可以通过
HTTPServer.config.get()
获取对当前配置的引用。也许是这样的:

class HTTPServer {
  public static final AtomicReference<ServerConf> config = 
    new AtomicReference(new ServerConf());
}
Worker w = new Worker(s, HTTPServer.config.get());
HTTPServer.config.set(new ServerConf(8080, new File("/foo/bar"));
loadConfig()
可以通过以下方式设置新配置:

class HTTPServer {
  public static final AtomicReference<ServerConf> config = 
    new AtomicReference(new ServerConf());
}
Worker w = new Worker(s, HTTPServer.config.get());
HTTPServer.config.set(new ServerConf(8080, new File("/foo/bar"));

如果同时更改所有配置并不重要,您可以跳过
ServerConf
类并将其用于端口设置,将
AtomicReference
用于根目录。

首先正确编写代码(即使用getter和所有工具),以后您可以担心性能。这些应该是常规的,
HTTPServer
的非静态最终字段,作为构造函数参数传入。另外,不要过早地进行优化——除非另有说明,否则getter几乎不需要任何成本。在我看来,您向我们提出了如何把它弄得一团糟的建议。您正在处理一个网络。与此相比,getter的开销是完全微不足道的,即使对于频繁读取的字段也是如此,您提到的字段肯定不是。