1

あいまいなタイトルで申し訳ありません - これをタイトルとしてどのように表現すればよいか思いつきませんでした。

基本的に、Java で単純なサーバー/クライアント プログラムを作成して遊んでいます。私のサーバーはスレッドを実行して新しい接続を常にチェックし、接続が見つかった場合は、その接続のためだけにスレッドと接続オブジェクトを作成します。

問題は、新しい接続をチェックするスレッドで発生します-エラーチェックを開始し、次の行に追加するまで、機能しませんでした:

System.out.println("");

突然、正常に動作するようになりました。この行を削除すると、接続用に新しいスレッドが追加されなくなります。スレッドが適切に実行されるのに十分な遅延を提供していると思ったので、しばらく for ループに入れて、それが機能するかどうかを確認しましたが、その単純な行以外は何も機能していません。

新しい接続スレッドを作成するためのコードは次のとおりです。

    class ThreadCreator implements Runnable {

    ThreadCreator() {

    }

    public void run() {
        while(true) {
            System.out.println("WHY DOES THIS WORK??");
            for(int i = 0; i < connections.size(); i++) {
                if(connections.get(i).thread == false) {
                    Runnable ReadRunnable = new Read(connections.get(i));
                    Thread ReadThread = new Thread(ReadRunnable, "MWHAHAH");
                    ReadThread.setPriority(Thread.MAX_PRIORITY);
                    ReadThread.start();
                    connections.get(i).thread = true;
                    System.out.println("THREAD CREATED");
                }
            }
        }
    }
}

何がうまくいかないのか想像できません..?

4

2 に答える 2

1

Joachim のおかげで、この問題をなんとか解決できました! 問題は、クライアントからメッセージを受信するために使用されるスレッドと、新しい接続を探すために使用されるスレッドが両方とも同じ変数 (接続のリスト) にアクセスしていたことです。

私は少量の調査を行い(http://jeremymanson.blogspot.co.uk/2008/11/what-volatile-means-in-java.html)、変数に volatile 修飾子を追加しました-私が知る限りオブジェクトを使用している他のすべてのスレッドに、オブジェクトが変更されたことを通知し、両方がアクセスできるようにします。

変数が複数のスレッドによって変更されている場合、スレッドの同期が重要であることも言及されました。ただし、私の変数はあるスレッドによって読み取られ、別のスレッドによって変更されていたので、ここでは volatile ステートメントで十分だったようです!

どうもありがとう!

于 2013-05-15T14:35:08.633 に答える
1

心に留めておくべきことの1つは、System.out.println()ほぼ確実に同期wait()どこかへの呼び出しが含まれることです(println()通常、フラッシュして、応答が表示される(または少なくとも他のプロセスに渡される)まで待機するため)。

これにより、同期に問題がある場合、マルチスレッド プログラムを簡単に「修正」できます。

于 2013-05-15T13:46:50.777 に答える