2

テキストベースのATコマンドを使用して単純なBluetooth周辺機器と通信するblackberryアプリを作成しています-モデムに似ています...イベントリスナーを使用してblackberryでのみ動作させることができます。したがって、通信は非同期になります。

ただし、これは単純なデバイスであり、同時アクセスを制御する必要があるため、ブロッキング コールのみを使用したいと考えています。

待機/通知を使用して通信をブロッキングに変換しようとする次のコードがあります。しかし、実行すると、getStringValue が完了するまで notifyResults は実行されません。つまり、遅延に関係なく常にタイムアウトします。

btCon オブジェクトは、すでに別のスレッドで実行されています。

スレッド化で明らかな何かが欠けていると確信しています。誰か親切に指摘してくれませんか?

ありがとう

また、notifyAll が IllegalMonitorStateException で爆発することも追加する必要があります。

以前、単純なブール値フラグと待機ループで試しました。しかし、同じ問題が存在しました。notifyResult は、getStringValue が完了するまで実行されません。

public class BTCommand implements ResultListener{
    String cmd;
    private BluetoothClient btCon;
    private String result;

    public BTCommand (String cmd){
        this.cmd=cmd;
        btCon = BluetoothClient.getInstance();
        btCon.addListener(this);

        System.out.println("[BTCL] BTCommand init");
    }

    public String getStringValue(){
        result = "TIMEOUT";
        btCon.sendCommand(cmd);
        System.out.println("[BTCL] BTCommand getStringValue sent and waiting");

        synchronized (result){
            try {
                result.wait(5000);
            } catch (InterruptedException e) {
                System.out.println("[BTCL] BTCommand getStringValue interrupted");
            }
        }//sync
        System.out.println("[BTCL] BTCommand getStringValue result="+result);

        return result;
    }

    public void notifyResults(String cmd) {
        if(cmd.equalsIgnoreCase(this.cmd)){
            synchronized(result){
                result = btCon.getHash(cmd);
                System.out.println("[BTCL] BTCommand resultReady: "+cmd+"="+result);                
                result.notifyAll();
            }//sync
        }
    }

}
4

3 に答える 3

2

notifyResults と getStringValue の両方が同じオブジェクトに同期句を持っているため、getStringValues が最初に同期セクションに到達すると仮定すると、getStringValues が同期領域を出るまで、同期句の開始時に notifyResults がブロックされます。私が理解している場合、これはあなたが見ている動作です。

Nicholas のアドバイスはおそらく適切ですが、使用している BlackBerry API でこれらの実装が見つからない場合があります。生産者と消費者のパターンを見たいと思うかもしれません。

于 2012-01-23T19:27:25.353 に答える
0

コードは問題なく動作します。文字列変数の代わりにfinalオブジェクトを使用する場合。NPEやIMSEを入手できないことに驚いています。

フィールドの作成:

private final Object resultLock = new Object();

文字列フィールドの代わりに使用するように、同期されたすべてのセクションを変更しますresult

マジックナンバー5秒は好きではありません。nullの結果をアプリケーションのタイムアウトとして扱うことを願っています。

于 2012-01-23T20:16:40.907 に答える
0

Brian Goetz の著書 Java Concurrency in Practice で推奨されているようLatchに、 、Semaphore、またはを使用する方が適切な場合があります。Barrier

これらのクラスを使用すると、ブロッキング メソッドを簡単に記述できるようになり、特に および に慣れていない場合は、バグを防ぐのに役立つ可能性がwait()ありnotifyAll()ます。(私はあなたがなじみがないことを示唆しているわけではありません。それは他の人のための単なるメモです...)

于 2012-01-23T17:30:09.817 に答える