0

この質問は長くなるかもしれませんが、多くの情報を提供したいと思います。

概要: Blackberry 用の株価情報アプリを作成しています。しかし、個々の Stock 情報を含む StringBuffer に問題があります。

プロセス: アプリは SocketConnection 経由でサーバーに接続します。サーバーは、最新の株式取引を含むフォーマットされた一連の文字列を送信します。したがって、新しい取引が発生するたびに、サーバーはその取引の個別の株価を送信します。InputStream を介して、その情報を読み取り、Threads によって参照される StringBuffer に各文字を配置できます。char3に基づいて解析することで、株価/情報のセットを特定できます。

char1 - データを分離するため char3 - 株価/情報の終わりを意味します

サーバーから送信されるサンプルの株価情報フォーマット: stock_quote_name(char 1)some_data(char1)some_data(char1)(char3)

次に、私のアプリはその株価情報を解析して特定のデータを比較し、画面に表示されるときにどのように見えるかをフォーマットします。取引が徐々に(ゆっくり)行われると、アプリは完全に機能します。でも..

問題: 取引があまりにも速くほぼ同時に発生すると、アプリは送信された情報を効率的に処理できません。StringBuffer の内容は、次のトレードと組み合わされています。意味 1 つの StringBuffer に 2 つの株式情報。

フィールドは次のようになります: Stock_quote_name some_data some_data

何が起こっているかのサンプル: Stock_quote_name some_data some_dataStock_quote_name some_data some_data

この部分の私のコードは次のとおりです。

while (-1 != (data = is.read()))
                {
                       sb.append((char)data);
                       while(3 != (data = is.read()))
                       {
                           sb.append((char)data);
                       }
                       UiApplication.getUiApplication().invokeLater(new Runnable()
                       {
                           public void run()
                           {
                               try
                               {
                                   synchronized(UiApplication.getEventLock())
                                   {
                                       SetStringBuffer(sb);
                                       DisplayStringBuffer();
                                       RefreshStringBuffer();
                                   }
                               } catch (Exception e)
                               {
                                   System.out.println("Error in setting stringbuffer: " + e.toString());
                               }
                           }
                       });
                }

public synchronized void DisplayStringBuffer()
{
    try
    {
        //parse sb - string buffer
        ......
    }
    catch(Exception ex)
    {
        System.out.println("error in DisplayStringBuffer(): " + ex.toString());
    }
}
public synchronized void SetStringBuffer(StringBuffer dataBuffer)
{
    this.sb =dataBuffer;
    System.out.println(sb);
}
public synchronized void RefreshStringBuffer()
{
    this.sb.delete(0, this.sb.length());
}

私が見ることができることから、取引が非常に高速に行われると、StringBuffer はすぐには更新されず、新しいデータを入力しようとすると以前の取引の内容が残っています。

私の質問は次のとおりです。 次の情報を最初のコンテンツに追加せずに、データを StringBuffer に入れる方法について何か提案はありますか?

4

3 に答える 3

0

そうですね、invokeLaterを使用してStringBufferを設定/表示/クリアしているので、その通りです。次のread()呼び出しに戻って、そのStringBufferを表示する前に変更することを妨げるものは何もありません。

明らかに、イベントスレッドからの入力ストリームから読み取っていないため、UIを更新するには、invokeLaterを使用するか、イベントロックで同期する必要がありますが、両方を実行しています。

invokeLaterを使用する場合は、イベントスレッドがUIにデータを表示しようとしているときに、入力ストリームリーダースレッドを使用してStringBufferに追加しないようにする必要があります。したがって、Runnableごとに新しいStringBufferを作成することを検討するでしょう。

イベントロックで同期する場合は、このようなものが機能する可能性があります(新しいRunnables / StringBuffersを作成することで、不要なガベージの作成を回避できるため、より適切に機能する可能性があります)。

while (-1 != (data = is.read()))
            {
                   sb.append((char)data);
                   while(3 != (data = is.read()))
                   {
                       sb.append((char)data);
                   }

                   synchronized(UiApplication.getEventLock())
                   {
                       SetStringBuffer(sb);
                       DisplayStringBuffer();
                       RefreshStringBuffer();
                   } 
            }
于 2010-05-10T03:34:30.453 に答える
0

UI スレッドが最後の株価の表示を完了する前に次の株価を読み取っているため、株価ごとに同じ StringBuffer を再利用することはできません。あるスレッドで StringBuffer に書き込み、別のスレッドで StringBuffer を読み取っていることを思い出してください。UI スレッド (読み取りスレッド) が RefreshStringBuffer() を呼び出してからループが繰り返され、次の株価情報を StringBuffer に追加し始めるという保証はありません。

代わりに文字列のコレクションを使用してください。

java.util.queue<String> q = new java.util.concurrent.ConcurrentLinkedQueue<String>();

次にq.add(sb.toString());、見積もりをsbに入れ終わったら実行します。

引用符を表示するには

public void DisplayStockQuote() {
    while(!q.isEmpty()) {
        String s = q.poll();

        // display s
        try
        {
            //parse s - string containing stock quote
            ......
        }
        catch(Exception ex)
        {
            System.out.println("error in DisplayStringBuffer(): " + ex.toString());
        }

    }
}

代わりにUIスレッドからそのメソッドを呼び出します

SetStringBuffer(sb);
DisplayStringBuffer();
RefreshStringBuffer();

余分なスレッドを避けて、Bradley のソリューションを使用することをお勧めします。しかし、本当に 2 つのスレッドが必要な場合は、このようなものが機能します。

于 2010-05-10T04:39:14.567 に答える