何を終わらせるべきなのですか?
- ここから 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含むブロックがあります。staticstatic { 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の子のオブジェクトを作成できるように作成しますBindTransmitterDataSMOutbindcreatePDU
したがって、テスト アプリケーションが実行されると、ONE
Threadは PDU の静的メソッドに入ります (初期化中DataSM)。そして、Thread初期化を開始した TWO は、OutbindONE の初期化が完了するのを待ちますPDU。しかし、 の静的メソッドを実行している ONE のある時点で、
PDUを初期化しようとしOutbind、TWO がすでに同じことを開始していることを確認して、TWO が終了するのを待ちます。だからONEとTWOはお互いが終わるのを待っている
この問題が静的ブロックの読み込みに関連していると確信するにはどうすればよいですか?
テスト コードの main メソッドの最初のステートメントとして次の 1 行を追加すると、動作し、Threads はブロックされなくなります。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 です。ファイル、データベースなどの外部リソースを保持しません。