-1

私はこのようにコードを持っています、

public int handle_refresh(Data mmsg) throws Exception {
        String custId = mmsg.getCustomerId();       
        CustomerThread t = custMap.get(mmsg.getCustomerId());
        if (t == null || !t.isAlive()) {
            t = (CustomerThread) context.getBean("custT");
            t.initThread(mmsg.getCustomerId(), mmsg.getCustomerId(), mmsg.getMessageBody());
            custSMap.put(mmsg.getCustomerId(), t);
            t.createBufferThread();
            t.start();
            t.initStreaming();
        }
        synchronized (t) {
            if (null != t) {
                ret = t.addSymbols(mmsg);
            }
        }
        return ret;
    }


                        }

ここで、CustomerThreadはcustMapでチェックされます。

マップcustMap=new CustomerThread();

スレッドがcustMapにある場合

1)次に、春の適用コンテキストを読んで取得します。t = (CustomerThread) context.getBean("custT");

2)initThreadメソッドで、顧客ごとに一意のスレッド名を設定します。 t.initThread(mmsg.getCustomerId(), mmsg.getCustomerId(), mmsg.getMessageBody());

3)次に、新しく作成したスレッドをマップに配置します custMap. custSMap.put(mmsg.getCustomerId(), t);

4)次に、createBufferThreadでデータがキャッシュに設定されます。t.createBufferThread();

5)次に、スレッドを新たに開始し、dbからデータを取得します。 t.start();

6)データベース接続を設定します

スレッドがcustMapにない場合

1)synchronized (t) .

2)t.addSymbols()メソッドを呼び出します。

私の質問は...

1)最初のifブロックは最初にのみ実行され、スレッドが作成されると常に同期(t)が実行されますか?

ブロックが1回だけ実行される場合、上記の1〜6ステップすべてを意味しますか?

2)では、同期(t)は何をしますか?

4

2 に答える 2

1

メソッドをスレッドセーフにするためにsychronized (t)保護しているように見えます。このメソッドの呼び出しは、スレッドaddSymbols内のデータ構造にシンボルを追加していると思います。tそのスレッドの他のメソッドがインスタンスsynchronizedをロックしていることを意味している可能性がありThreadます。それsychronized (t)がここで行っていることです。

しかし、これはスレッドセーフを追加する非常に醜い方法です。addSymbols(...)メソッド自体がロックオブジェクトをロックするか、必要に応じてメソッドにする必要がありsynchronizedます。クラスはそれ自体のロックに責任があり、呼び出し元が何かをする必要はありません。

あなたのコードに関する他のコメントをいくつか挙げてください。

t = (CustomerThread) context.getBean("custT");

上記のコードは、Springからスレッドインスタンスを取得しているようです。「custT」Beanがある種のスレッドファクトリでない限り、これは通常シングルトンです。ファクトリBeanでない場合は、handle_refreshメソッドの呼び出しごとに同じスレッドオブジェクトを取得し、それを再初期化します。これはおそらくあなたが望むものではありません。

synchronized (t) {
    if (null != t) {
        ret = t.addSymbols(mmsg);
    }
}

もしそうなら、ラインtはNPEをスローします。の内部をチェックする必要はありません。nullsynchronizednullsynchronized

CustomerThread t = custMap.get(mmsg.getCustomerId());

メソッドが複数のスレッドから呼び出される場合は、も適切に同期されているhandle_refresh(...)ことを確認する必要があります。custMap

于 2012-09-10T12:28:57.243 に答える
0

ifブロックは、顧客IDごとに1回だけ実行する必要があります。ifブロックの次のコード行に注意してください。

custSMap.put(mmsg.getCustomerId(), t);

マップにデータが入力されるため、次にそのcustomerIdを使用して検索が実行されると、マップが検出され、同期されたブロックが実行されます。

Synchronizedブロックは、ミューテックスロック内のtでメソッドを呼び出します。

于 2012-09-10T12:27:55.077 に答える