我正在开发一个用Java编写的网络服务器。 Web服务器正在处理与客户端的websocket通信,因此我们有一个名为ClientHandler的类,它有一个socket和id作为实例变量。 ClientHandler需要有一个侦听来自客户端的消息的函数。这个函数需要与paralell一起工作到服务器的其余部分,并且由于“读取消息”是一个线程阻塞函数,我们需要一个单独的线程。
以下是实现此目的的两种替代方法:
public class ClientHandler implements Runnable{
//Instance variable
public Thread listener = new Thread(this);
.
.
.
public void run() {
while (!Thread.interrupted()){
//Listening code here
}
}
}
然后通过编写
启动监听器线程clientHandler.listener.start();
通过写
来阻止它clientHandler.listener.interrupt();
或者这个方法:
public class ClientHandler {
//Instance variable
private Thread listenerTread;
private boolean alive; //set to true in constructor
.
.
.
public void listenToClient() {
listenerTread = new Thread(new Runnable() {
@Override
public void run(){
while (!alive){
//Listening code here
}
}
});
}
}
然后通过调用函数listenToClient()
来启动线程clientHandler.listenToClient();
并通过切换alive = false来停止它。
我试图找人解释最佳解决方案,但大多数比较是在实现Runnable或扩展Thread之间。使用上述任何一种方法有任何缺点吗?如果我想在一个类中拥有多个线程,最好的方法是什么?
答案 0 :(得分:2)
我不确定您是否要显式创建Thread实例。为什么不尝试使用ThreadPoolExecutor来提交执行任务。在这里阅读更多关于线程池http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
由于您可以拥有多个客户端,因此使用线程池可以提高应用程序的性能。
答案 1 :(得分:0)
你有两个任务。一种是监听新连接并开始提供连接。其次是实际提供连接。在单独的线程内为每个连接提供服务的决定是第二个任务的实现细节。原则上,它可以通过线程池或异步IO以其他方式提供。因此,此实现细节应隐藏在第二个任务的代码中,并且不得对第一个任务的代码可见。所以使用第二种方式。