2016-10-12 34 views
0

在我的Java應用程序中,我希望有一個線程池(爲此,我使用ExecutorService)連接到memcached服務器以發出一些請求。我希望每個線程都有自己的連接,打開一次並在整個運行時間內保持連接。我正打算使用下面的代碼,我在另一個問題發現:初始化ThreadLocal變量時傳遞參數

執行人服務

ExecutorService threadPool = 
Executors.newFixedThreadPool(5, Executors.defaultThreadFactory()); 

的Runnable由線程池中

public class SocketTask implements Runnable { 
private String workDetails; 
private static final ThreadLocal<Socket> threadLocal = 
     new ThreadLocal<Socket>(){ 
    @Override 
    protected Socket initialValue(){ 
     return new Socket(); 
    }   
}; 

public SocketTask(String details){    
    this.workDetails = details; 
} 

public void run(){  
    Socket s = getSocket(); //gets from threadlocal 
    //send data on socket based on workDetails, etc. 
} 

public static Socket getSocket(){ 
    return threadLocal.get(); 
} 

}

執行

我的問題是,當我初始化套接字如何做到這一點o我能夠通過一個參數(比如說一個帶有memcached服務器的IP的String)到新的Socket()調用中?

回答

0

java.net.Socket類可以用重載的構造函數初始化。符合您的要求接近的一個可能是以下幾點:

Socket socket = new Socket("yourHost", yourPort); 

也...

  • 您可以使用static字段定義主機和端口,並在initialValue引用它們簡單地用字段的名稱

SocketTask.this.[theFieldNames]

API

+0

事情是「yourHost」將存儲在一個變量(也許類SocketTask的屬性),你怎麼做,所以它是可見的intialValue()方法內? – Moises

+0

@Moises看到我的編輯。 – Mena

+0

@Moises更多編輯。弄糊塗了我自己。現在應該更清楚了。 – Mena

0

使用工廠而不是靜態字段的示例。

廠創建:

final SocketTaskFactory socketTaskFactory = new SocketTaskFactory("...", 12345); 

廠使用(而不是現在的 「新SocketTask(...)」):

Runnable socketTask = socketTaskFactory.createSocketTask("the work details"); 

廠代碼,包括插座任務作爲一個內部類:

package threadlocal; 

import java.io.IOException; 
import java.net.Socket; 

public class SocketTaskFactory 
{ 
    final String host; 
    final int port; 

    public SocketTaskFactory(String host, int port) 
    { 
     this.host = host; 
     this.port = port; 
    } 

    public Runnable createSocketTask(String workDetails) 
    { 
     return new SocketTask(workDetails); 
    } 

    final ThreadLocal<Socket> socketForThread = new ThreadLocal<Socket>() 
    { 
     @Override 
     protected Socket initialValue() 
     { 
      try 
      { 
       return new Socket(host, port); 
      } 
      catch(IOException exception) 
      { 
       throw new RuntimeException(exception); 
      } 
     } 
    }; 

    private class SocketTask implements Runnable 
    { 
     private final String workDetails; 

     public SocketTask(String workDetails) 
     { 
      this.workDetails = workDetails; 
     } 

     @Override 
     public void run() 
     { 
      Socket socket = socketForThread.get(); 

      // ... 
     } 
    } 
} 
+0

我覺得ThreadLocal應該在類SocketTask裏面沒有? – Moises

+0

然後每個SocketTask實例都有它自己的ThreadLocal實例,這正是不起作用的。否則,你就不會有這個問題,首先問這個問題。 – yeoman

+0

工廠只是讓事情不是靜態的一種方式。每個工廠仍然只有一個,許多實例都有一個。但它比使用靜態字段更靈活,這通常是一個壞主意,因爲它經常需要改變它,並且在不久的將來某些時候使它不是靜態的。 – yeoman