我用Java编写了一个小型HTTP服务器,我在将静态变量(服务器配置:端口,root等)传递给处理请求的线程时遇到了问题。我不希望我的线程修改这些变量,如果它扩展了服务器类,它也将继承我不想要的方法。
出于性能原因,我不想使用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作为嵌套类。它在另一个包中......
你有什么建议?
答案 0 :(得分:2)
您可以将配置放入最终AtomicReference。然后它可以由您的工作人员引用,也可以以线程安全的方式更新。
类似的东西:
class HTTPServer {
public static final AtomicReference<ServerConf> config =
new AtomicReference(new ServerConf());
}
使新的ServerConf
类不可变:
class ServerConf {
final int port;
final File root;
public ServerConf(int port, File root) {
this.port = port;
this.root = root;
}
}
然后,您的工作人员可以通过HTTPServer.config.get()
获取对当前配置的引用。也许是这样的事情:
Worker w = new Worker(s, HTTPServer.config.get());
loadConfig()
可以通过以下内容设置新配置:
HTTPServer.config.set(new ServerConf(8080, new File("/foo/bar"));
如果同时更改所有配置并不重要,则可以跳过ServerConf
类并使用AtomicInteger
作为端口设置,并使用AtomicReference<File>
作为根目录。
答案 1 :(得分:0)
将静态数据读入静态“sharedConfig”对象,该对象也有一个套接字字段 - 您可以将该字段用于侦听套接字。当acccpet()返回服务器&lt;&gt;客户端套接字,clone()'sharedConfig',推入新套接字并将该对象传递给服务器&lt;&gt;客户端工作线程。然后线程获得它可以erad甚至修改的配置的副本,如果它想要不影响任何其他线程或静态配置。