2

Javaでは、クライアントに2つのスレッドがあり、1つはネットワークフローを制御し、もう1つはメッセージを処理し、ゲームを描画します。私がやろうとしているのは、パケットが来ると、ネットワークスレッドがmessageReceivedメソッドを呼び出すことです.パラメータとしてメッセージを含むゲーム スレッド。関数 messageReceived を同期として作成し、messageReceived 関数が終了する前に 2 つのパケットが順番に来る場合、ネットワーク スレッドをブロックしますか、またはネットワーク スレッドが既に使用されている messageReceived 関数を呼び出すことができなかったため、ブロックされず、パケットが失われますゲームスレッドで?

4

6 に答える 6

0

はい、synchronized暗黙的なロックが別のスレッドによって既にロックされている場合、スレッドをブロックします。しかし、非ブロッキングの代替手段があります -java.util.concurrent.locks.Lockそれはより柔軟です

Lock.tryLock()
  • 呼び出し時に解放されている場合にのみロックを取得します

Lock.tryLock(long time, TimeUnit unit)
  • 指定された待機時間内に解放され、現在のスレッドが中断されていない場合、ロックを取得します。
于 2013-05-03T17:53:53.477 に答える
0

オブザーバー パターンなどのより主流のデザイン パターンを使用すれば簡単に回避できる問題を解決しようとしているように思えます。http://en.wikipedia.org/wiki/Observer_pattern

于 2013-05-03T17:51:45.633 に答える
0

正解です。IO スレッドでブロックしています。そのため、 messageReceived() で軽い作業のみを実行したい...おそらく、処理スレッドが後で作業できるように、メッセージをある種の FIFO にキューに入れるだけです。同期ブロックのフットプリントはできるだけ小さくする必要があります。

于 2013-05-03T17:50:29.157 に答える
0

スレッドがクラス内の同期メソッドを呼び出すと、オブジェクト ロックが使用できないため、他のすべてのスレッドはそのクラス内の同期メソッドを呼び出すことがブロックされます。messageReceived がどの共有リソースでも機能していない場合は、非同期のままにしてください。共有リソースを使用している場合は、そのコードを同期ブロックにラップして、同期コードを最小化してみてください。

于 2013-05-03T17:50:49.000 に答える
0

概念化するのは簡単ですが、私はより視覚的な人です。これは、excatly syncorized が何を行い、どのように機能するかをずっと前に理解するのに役立つコードです。出力を見ると、synced 属性を print 関数に追加すると、As と B が混在していないことがわかります。しかし、それを削除すると、まったく異なる出力が表示されます。一度見たらすぐにわかるはずです。

public class Main {
    public static void main(String[] args) {
        (new ThreadA()).start();
        (new ThreadB()).start();
    }

    // try it with removing the synchronized:  public static void print(String str) {
    public static synchronized void print(String str) {
        for(int i = 0; i<100; i++)
            System.out.print(str);
        System.out.println();
    }

    public static class ThreadA extends Thread {
        public void run() {
            while(true) {
                print("A");
            }
        }
    }
    public static class ThreadB extends Thread {
        public void run() {
            while(true) {
                print("B");
            }
        }
    }
}
于 2013-05-03T17:58:35.440 に答える