ServerSocket と Sockets をより適切に制御するために非常に基本的な API を実装していますが、スレッドに関する知識がないために修正できない非常に奇妙な問題に直面しています。説明させてください。
私のクラス SocketStreamReceiver では、セカンダリ スレッドを使用して新しいソケットをリッスンしServerSocket#accept()
ます。クライアントが SocketStreamReceiver を開始 (スレッドを作成してリッスンを開始accept()
) および停止 (ServerSocket を閉じてスレッドを破棄) するために使用できる start() と stop() の 2 つのメソッドがあります。
stop() メソッドをどのように実装しますか? stop() は、doSomething() 内で、start() によって開始された同じセカンダリ スレッドで呼び出すことができることに注意してください。好きなように変更できます。必要に応じて、while(running) の直前に、スレッド内に ServerSocket を作成できます。
public class SocketStreamReceiver{
...
private Thread thread;
private ServerSocket server;
private boolean running;
...
public void start () throws IOException{
if (thread != null) return;
server = new ServerSocket (port);
thread = new Thread (new Runnable (){
@Override
public void run (){
try{
while (running){
Socket socket = server.accept ();
doSomething (socket);
}
}catch (SocketException e){
...
}catch (IOException e){
...
}
}
}, "SocketStreamReceiver");
thread.start ();
}
public void stop () throws IOException{
if (thread == null) return;
//code...
thread = null;
}
}
ありがとう。
編集 - 解決策:
public class SocketStreamReceiver{
private Thread thread;
private ServerSocket server;
private volatile boolean running;
...
public synchronized void start () throws IOException{
if (thread != null) throw new IllegalStateException ("The receiver is already started.");
server = new ServerSocket (port);
thread = new Thread (new Runnable (){
@Override
public void run (){
try{
running = true;
while (running){
doSomething (server.accept ());
...
}
}catch (SocketException e){
...
}catch (IOException e){
...
}
}
}, "SocketStreamReceiver");
thread.start ();
}
public synchronized void stop (){
if (thread == null) return;
running = false;
try{
if (server != null){
server.close ();
}
}catch (IOException e){}
thread = null;
}
}