私は根本的な原因を理解できないという珍しい問題があるようです。JavaのServerSocketがスレッドをハングし、ブレークポイントを置くとロックが解除されますか?
私が書いているサーバーへの接続を処理するのにServerSocketを使用しています。 ServerSocketは独自のスレッドで接続を受け入れ、設定したisAcceptingとisActive変数を介してメインスレッドから制御できます。
何が起こるか: サーバーは接続を開始し、(パテ経由で)接続を受け入れています。私はコマンドを使用してサーバーソケットを閉じます。ソケットが閉じられ、スレッドがアイドル状態になります(これが原因でSocketExceptionが発生することがわかります)。私は、新しいサーバーソケットを開くためのコマンドを使用し、再度接続を受け付けます。私は接続することができるよとソケットをシャットダウンし、何が起こるループの接続を受け入れること
出てコマンドを経由してアプリケーションを終了することができます
サーバの起動をし、(パテ経由)接続を受け入れているが。私はコマンドを使用してサーバーソケットを閉じます。ソケットが閉じられ、スレッドがアイドル状態になります(これが原因でSocketExceptionが発生することがわかります)。私は新しいサーバーソケットを開くコマンドを使用し、それはスレッドがハングする場所です。コード内のデバッグ情報は表示されず、ServerSocketのオープン/クローズにも反応しません。 Exitコマンドを使用すると、exitルーチンでアプリケーションがハングアップします。面白いのは、スレッドコードのどこにでもブレークポイントを設定すると、そのスレッドは元に戻って終了し、終了します。コードを正常に実行するには、ブレークポイントを配置するまでソケットを閉じてスレッドを閉じます。
実行可能なJARにエクスポートしようとしましたが、Eclipseの場合と同様に、終了時にアプリケーションがハングします。以下のコードの
関連部品:私は、コードにブレークポイントを置くまで
public class ConnectionManager extends Thread implements IEverfreeManager {
private final int defaultPort = 8002;
private boolean isAccepting = true;
private boolean isActive = true;
private static ConnectionManager instance;
private ServerSocket serverSocket;
private int portNumber = defaultPort;
private Socket workSocket;
public static ConnectionManager instance(){
if (instance == null)
instance = new ConnectionManager();
return instance;
}
public ConnectionManager() {
}
public boolean isAccepting() {
return isAccepting;
}
public void setAccepting(boolean isAccepting) {
this.isAccepting = isAccepting;
try{
if (!isAccepting && !serverSocket.isClosed()){
serverSocket.close();
System.out.println("Closed server on port "+portNumber);
} else{
serverSocket = new ServerSocket(portNumber);
System.out.println("Server on port "+portNumber+" is now accepting connections");
}
}catch(Exception e){
System.out.println("failed to stop accepting");
e.printStackTrace();
}
}
public boolean isActive() {
return isActive || isAlive();
}
public void setActive(boolean isActive) {
this.setAccepting(isActive);
this.isActive = isActive;
}
public int getPortNumber() {
return portNumber;
}
public void setPortNumber(int portNumber) {
this.portNumber = portNumber;
}
private int getNewConnectionId(){
return ++connectionIdCounter;
}
@Override
public void run() {
super.run();
try {
System.out.println("Starting up Connection Manager");
System.out.println("Starting server on port "+portNumber);
serverSocket = new ServerSocket(portNumber);
System.out.println("Server running and ready to accept players");
while (isActive){
if (isAccepting){
try{
System.out.println("Waiting for connection...");
workSocket = serverSocket.accept();
System.out.println("Connected with "+workSocket.getInetAddress());
int id = getNewConnectionId();
} catch (SocketException e){
System.out.println("Notice: "+e.getMessage());
}
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
@Override
public void closeManager() {
setActive(false);
}
はsetAccepting(false)を使用して、setAccepting(真)は
System.out.println("Waiting for connection...");
メッセージを生成しません。
setAccepting(false)の後にcloseManager()を使用すると、同じ結果が生成されます。ただcloseManagerを(使用
)setAcceptingに触れることなく()(シャットダウン時にアクティブ化手順を持つにもかかわらず)正常に終了し
任意の洞察力は非常に
ありがとうございます!揮発性のキーワードがトリックでした。あなたのアドバイスに従ってクラスを修正しようとします –