初始化ThreadLocal变量时传递参数

时间:2016-10-12 12:12:01

标签: java multithreading sockets

在我的Java应用程序中,我希望有一个线程池(我使用ExecutorService)连接到memcached服务器以发出一些请求。我希望每个Thread都有自己的连接打开一次,并且应该在整个运行时间内保留。我打算使用我在另一个问题中找到的以下代码:

执行人服务

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

由池中的线程执行的Runnables

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();
}

}

我的问题是,当我初始化套接字时,我怎么能这样做,所以我能够将一个参数(比如一个带有memcached服务器IP的字符串)传递给新的Socket()调用?

3 个答案:

答案 0 :(得分:0)

可以使用重载的构造函数初始化java.net.Socket类。符合您要求的那个可能更接近:

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

同时...

  • 您可以使用static字段来定义主机和端口,并使用字段名称在initialValue中引用它们

SocketTask.this.[theFieldNames]

请参阅API

答案 1 :(得分:0)

工厂而不是静态字段的示例。

工厂创建:

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

工厂使用(而不是现在&#34;新的SocketTask(...)&#34;):

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();

            // ...
        }
    }
}

答案 2 :(得分:0)

或者您可以像创建ThreadLocal<Socket> soc = new ThreadLocal<>();一样创建ThreadLocal,并在需要时使用可能需要的任何构造函数/参数检查if (soc.get() == null) {soc.set(...);}