何を終わらせるべきなのですか?
- ここから logica smpp jar (215 KB) をダウンロードします: http://opensmpp.logica.com/CommonPart/Download/library_1_3/smpp_full.tar.gz
小さなテスト コードを記述します。
package com.logica.smpp; import com.logica.smpp.pdu.DataSM; import com.logica.smpp.pdu.Outbind; public class PDUTest { public static void main(String... args) throws InterruptedException { Thread thread1 = new Thread(new Runnable() { @Override public void run() { System.out.println(new DataSM().debugString()); } }); thread1.setName("ONE"); Thread thread2 = new Thread(new Runnable() { @Override public void run() { System.out.println(new Outbind().debugString()); } }); thread2.setName("TWO"); thread1.start(); thread2.start(); } }
この
main
メソッドを実行します。
何が起こるのですか?
はThread
ブロックされています (おそらくお互いを待っています)
私の分析:
DataSM
とクラスの両方にOutbind
共通の祖先があり、次のコードをPDU
含むブロックがあります。static
static { pduList = new Vector(30,4); pduList.add(new BindTransmitter()); pduList.add(new BindTransmitterResp()); pduList.add(new BindReceiver()); pduList.add(new BindReceiverResp()); pduList.add(new BindTransciever()); pduList.add(new BindTranscieverResp()); pduList.add(new Unbind()); pduList.add(new UnbindResp()); pduList.add(new Outbind()); pduList.add(new SubmitSM()); pduList.add(new SubmitSMResp()); pduList.add(new SubmitMultiSM()); pduList.add(new SubmitMultiSMResp()); pduList.add(new DeliverSM()); pduList.add(new DeliverSMResp()); pduList.add(new DataSM()); pduList.add(new DataSMResp()); pduList.add(new QuerySM()); pduList.add(new QuerySMResp()); pduList.add(new CancelSM()); pduList.add(new CancelSMResp()); pduList.add(new ReplaceSM()); pduList.add(new ReplaceSMResp()); pduList.add(new EnquireLink()); pduList.add(new EnquireLinkResp()); pduList.add(new AlertNotification()); pduList.add(new GenericNack()); }
で提供されるファクトリメソッドを介して、、などpduList
の子のオブジェクトを作成できるように作成しますBindTransmitter
DataSM
Outbind
createPDU
したがって、テスト アプリケーションが実行されると、ONE
Thread
は PDU の静的メソッドに入ります (初期化中DataSM
)。そして、Thread
初期化を開始した TWO は、Outbind
ONE の初期化が完了するのを待ちますPDU
。しかし、 の静的メソッドを実行している ONE のある時点で、
PDU
を初期化しようとしOutbind
、TWO がすでに同じことを開始していることを確認して、TWO が終了するのを待ちます。だからONEとTWOはお互いが終わるのを待っている
この問題が静的ブロックの読み込みに関連していると確信するにはどうすればよいですか?
テスト コードの main メソッドの最初のステートメントとして次の 1 行を追加すると、動作し、Thread
s はブロックされなくなります。Class.forName("com.logica.smpp.pdu.PDU");
私の質問は次のとおりです。
- 私の分析は正しいですか?
Thread
これは、静的ブロックに関する既知の同期の問題ですか?- この状況に陥らないようにするために実践する必要がある経験則はありますか?
アップデート
ここに PDU のファクトリ メソッドを追加します。
public static final PDU createPDU(int commandId) { int size = pduList.size(); PDU pdu = null; PDU newInstance = null; for (int i = 0; i < size; i++) { pdu = (PDU)pduList.get(i); if (pdu != null) { if (pdu.getCommandId() == commandId) { try { newInstance = (PDU)(pdu.getClass().newInstance()); } catch (IllegalAccessException e) { } catch (InstantiationException e) { } return newInstance; } } } return null; }
のコンストラクタ
DataSM
とOutbind
の他の子クラスはPDU
何をしますか?
いくつかのインスタンス変数を初期化する以外は何もありません。これらは POJO です。ファイル、データベースなどの外部リソースを保持しません。