2012-04-18 63 views
2

我用Java編寫了一個小型HTTP服務器,並且遇到了將靜態變量(服務器配置:端口,根等等)傳遞給處理請求的線程的問題。我不想讓我的線程修改這些變量,如果它擴展了服務器類,它也會繼承我不想要的方法。將靜態字段傳遞給線程

由於性能原因,我不想使用getter。如果我使靜態成員最終,我將有一個問題時,從配置文件加載它們的值。

這裏是一個例子

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 
} 

我也不想有工人爲嵌套類。它在另一個包...

你有什麼建議?

+7

先對它進行正確的編碼(即使用getters和所有內容),稍後可能會擔心性能。 – biziclop 2012-04-18 21:30:02

+2

這些應該是'HTTPServer'的常規非靜態final字段,作爲構造函數參數傳入。另外,不要過早優化 - 除非另有分析,否則獲得者幾乎不需要花費任何代價。 – 2012-04-18 21:46:10

+0

在我看來,你問我們如何使它完全混亂的指針。 – 2012-04-18 22:02:18

回答

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>

0

將靜態數據讀入靜態'sharedConfig'對象中,該對象也具有套接字字段 - 您可以將該字段用於偵聽套接字。當acccpet()返回一個服務器客戶端套接字clone(),'sharedConfig'時,在新套接字中插入並將該對象傳遞給客戶端工作線程服務器。然後線程得到一個配置的副本,它可以消除甚至修改,如果它不想影響任何其他線程或靜態配置。