0

我有一个带有按钮的 Swing 表单,当单击该按钮时开始SocketServer监听单独线程中的传入请求。以下是我拥有的课程结构。

  • MainForm:这是我的主要课程,它启动了 Swing Form。它有两个按钮,“启动服务器”和“停止按钮”。
  • MySocketServer:这个类是SocketServer对象存在的地方,它有方法startServer()stopServer().

以下是开始按钮的点击事件正文。

t = new Thread(new Runnable() //Object t is created globally in this main class.
{
    public void run()
    {
        myss = new MySocketServer(); //Object myss has similar accessibility as t.
        myss.startServer();
    }
});
t.start();

以下是停止按钮的点击事件主体

myss.stopServer();
if(t.isAlive());
    System.out.println("Thread is still alive!!");

虽然我可以根据需要切换 SockeServer “开始”和“停止”,但我意识到每次启动服务器时,都会创建新线程并且即使使用MySocketServer's 方法停止服务器,它仍然保持活动状态。

我可以使用stop()Thread停止线程执行,但由于它已被贬值,而且我研究过线程在其run()方法完全执行后就会结束,但我将startServer()方法分开,以便它可以单独处理连接的客户端。

请注意,startServer()有 While-Listen 循环,因此run()线程方法本质上处于无限执行状态,直到我显式调用stopServer()并停止循环。

在这里可以做什么?

4

3 回答 3

1

首先,您不要尝试使用Thread.stop(). 这是潜在的危险。

那你该怎么办?

一种可能性可能是像这样编写您的服务器线程:

    ....
    ServerSocket ss = new ServerSocket(...);
    try {
       while (keepGoing) {
           Socket s = ss.accept(...);
           try {
               // do stuff
           } finally {
               // close socket
           }
       }
    } finally {
       // close the server socket
    }

stopServer清除keepGoing标志。但问题是,当线程在调用中被阻塞时,通常会停止accept,并且没有什么可以解除阻塞。

另一种可能性可能是调用Thread.interrupt()线程。这会导致某些事情解除阻塞并引发异常,但我认为它不会解除阻塞accept()调用。(但是,如果“做事”部分需要中断,这仍然比设置标志更好。)

真正的解决方案(我认为)是关闭ServerSocket. 这将导致ss.accept()调用解除阻塞并引发异常,您需要在服务器线程中处理该异常。

于 2012-06-09T06:43:32.030 回答
0

你不应该使用 stop()。看看这个http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html 带有无限循环和启动/停止标志的解决方案很简单,但会导致 CPU 时间的使用无效. 更好的方法是使用等待/通知方法。您使用 MySocketServer 操作的方式让我觉得您在 startServer() 中还有其他无限循环。这就是为什么你必须阻止它。最好在内部将此循环包装到它自己的线程中,并使启动/停止方法以等待/通知方式在此线程状态下运行。忘了提一下,当你的 GUI 在它自己的线程中运行时,你不能在 MySocketServer 中转义启动/停止标志,因为在 GUI 线程中使用 wait() 会使它挂起。

于 2012-06-09T06:26:43.960 回答
0

在 while 循环中的 MySocketServer 类中,您需要一个标志来测试它是否应该继续运行。

在您新添加的关闭方法中,设置线程中的循环将测试的标志。一旦循环中断并且 run() 返回,线程将结束。

于 2012-06-09T05:24:00.003 回答