0

ボタン付きのSwingフォームがあります。これは、クリックするSocketServerと、別のスレッドで着信要求をリッスンするために開始されます。以下は私が持っているクラスの構造です。

  • MainForm:これは、SwingFormを起動する私のメインクラスです。「サーバーの起動」と「停止」の2つのボタンがあります。
  • 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のメソッドを使用して停止してもアクティブなままであることに気付きます。

スレッドの実行を使用stop()して停止することはできますが、減価償却され、メソッドが完全に実行されるThreadとスレッドが終了することを調査したため、接続されたクライアントを個別に処理できるようにメソッドを分離しました。run()startServer()

startServer()While-Listenループがあることに注意してください。したがって、ループを明示的に呼び出して停止するrun()まで、基本的にスレッドのメソッドは無限の実行状態にあります。stopServer()

ここで何ができるでしょうか?

4

3 に答える 3

1

まず、使用しようとしないのは正しいことThread.stop()です。潜在的に危険です。

それで、あなたは何をすべきですか?

1 つの可能性として、サーバー スレッドを次のように記述します。

    ....
    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 は独自のスレッドで実行されるため、GUI スレッドで wait() を使用するとハングするため、MySocketServer 内の開始/停止フラグをエスケープできません。

于 2012-06-09T06:26:43.960 に答える
0

while ループの MySocketServer クラスでは、実行を継続するかどうかをテストするフラグが必要です。

新しく追加したシャットダウン メソッドで、スレッド内のループがテストするフラグを設定します。ループが壊れて run() が戻ると、スレッドは終了します。

于 2012-06-09T05:24:00.003 に答える