在a simple test case中,我实现了一个线程池服务器,在端口12345接受多达10个同时传入的TLS PSK连接,并以标准输出打印解密数据:
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(12345);
ExecutorService pool = Executors.newFixedThreadPool(10);
while (true) {
Socket socket = server.accept();
pool.execute(new MyRunnable(socket));
}
}
以下是线程使用的Runnable
实现:
@Override
public void run() {
try {
SecureRandom random = new SecureRandom(); // How to preallocate?
BufferedInputStream bis = new BufferedInputStream(mSocket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(mSocket.getOutputStream());
TlsServerProtocol proto = new TlsServerProtocol(bis, bos, random);
MockPSKTlsServer server = new MockPSKTlsServer(); // How to preallocate?
proto.accept(server);
Streams.pipeAll(proto.getInputStream(), System.out);
proto.close();
} catch (IOException e) {
System.err.print(e);
}
}
如何预分配SecureRandom
使用的MockPSKTlsServer
和Runnable
个对象?
即。如何在main()
中创建10个对象,然后在run()
中重复使用它们?
答案 0 :(得分:3)
在您的情况下,我会为每个班级SecureRandom
和MockPSKTlsServer
)使用ThreadLocal
,以便为SecureRandom
和MockPSKTlsServer
设置一个专用实例连接池的每个线程,当线程必须执行相同类型的任务但具有不同的输入Socket
时,重用它们,如:
private static final ThreadLocal<SecureRandom> random = ThreadLocal.withInitial(
SecureRandom::new
);
private static final ThreadLocal<MockPSKTlsServer> server = ThreadLocal.withInitial(
MockPSKTlsServer::new
);
...
public void run() {
try (BufferedInputStream bis = new BufferedInputStream(mSocket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(mSocket.getOutputStream());
TlsServerProtocol proto = new TlsServerProtocol(bis, bos, random.get())) {
// Calling server.get() will get the instance dedicated to the current
// thread, if no instance exists so far for this thread
// new MockPSKTlsServer() will automatically be called then
// affected to this thread for subsequent get's calls
proto.accept(server.get());
...
} catch (IOException e) {
System.err.print(e);
}
}
注意:使用try-with-resources
语句自动关闭输入/输出流。
答案 1 :(得分:2)
通常我会使用ThreadLocal<>
并使用轻量级Pool<T>
类来保存和提供实例。
我不认为开箱即用Pool<T>
,但这很简单。
使用ThreadLocal<>
的唯一考虑因素是您必须确保正确地释放回Pool<>
。因此,如果您正在考虑将此信息传达给另一个线程,更好的方法可能是共享的静态池,但要么是锁定(如果您不太关心性能),要么是并发容器,如果您这样做..