0

シリアル ポートを読み取り、データをプロットし、値を表示するプログラムを作成しました。ユーザーが GUI 内でデータ収集を停止できるようにしながら、SwingWorker を使用して値を収集、確認、およびプロットしています。値をプロットして正確な値を表示しようとすると、変更例外が発生していると思います。

以下は、doInBackground() の単純化されたバージョンです。私が消去した行は、基本的に、読み取った値のチェックと比較です。

protected Integer doInBackground() 
    while (true && !isCancelled()) {
        value = initandReadCOM();
        // I also check and compare the value
        publish(value);
    }
    return 0;
}

次に、processコマンドを使用してデータをプロットしています。私が見つけたこの問題に関する最も近いスレッドは、これを使用することを提案しました。

@Override
protected void process(List<Float> chunks) {
    super.process(chunks);
    float factor = chunks.get(chunks.size() - 1);
    seriesUpdated = getSeries();
    SetDataField(factor);
    this.seriesUpdated.add(new Millisecond(), factor);
}

問題の診断に必要な場合はSetDataField、その方法を以下に示します。seriesUpdated

public void SetDataField(float n) {
        this.data_.setText("Data: " + String.valueOf(n));
}

public TimeSeries getSeries() {
        return this.series;
}

プログラムが長時間実行されると、この例外がより頻繁に発生し始めます。ありとあらゆる助けをいただければ幸いです。

また、何か他に役立つ情報が必要な場合はお知らせください。ありがとう

編集:以下はスタックトレースです

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at java.util.Collections$UnmodifiableCollection$1.next(Unknown Source)
    at org.jfree.chart.plot.XYPlot.drawRangeMarkers(XYPlot.java:4088)
    at org.jfree.chart.plot.XYPlot.draw(XYPlot.java:3281)
    at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1226)
    at org.jfree.chart.ChartPanel.paintComponent(ChartPanel.java:1612)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JComponent.paintToOffscreen(Unknown Source)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
    at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
    at javax.swing.RepaintManager.paint(Unknown Source)
    at javax.swing.JComponent._paintImmediately(Unknown Source)
    at javax.swing.JComponent.paintImmediately(Unknown Source)
    at javax.swing.RepaintManager$3.run(Unknown Source)
    at javax.swing.RepaintManager$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.access$1000(Unknown Source)
    at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
4

1 に答える 1

0

JFreeChart のデータ モデルを変更していますが、ペイントするために UI スレッド内からそのモデルにアクセスする可能性があります。これを修正するには、さまざまなオプションがあります。

  1. バックグラウンド スレッドが結果を計算し、モデルCollectionから独立して に格納します。JFreeChart次に、UI スレッド内でモデルを更新します。これは、チャート モデルを UI パーツと考える最も簡単なアプローチですが、UI スレッド内で多くの作業を行うことになる可能性があります。

  2. 複数のチャート モデルを使用します。レンダリングされるグラフで現在使用されているものとは異なるグラフ モデルを更新します。次に、UI スレッド内のチャートに新しいモデルを設定して、UI を更新します。これにより、特定のチャート固有の計算をバックグラウンド スレッドで実行できるようになり、現在のコードに最小限の変更を加えるだけで実装できます。ただし、更新のたびにチャート モデル全体が再計算されるため、増分変更がかなり小さい場合は非効率になる可能性があります。

  3. チャート コード全体をバックグラウンド スレッドに移動します。これは最も急進的な変更かもしれませんが、最も効率的な解決策です。このソリューションでは、チャートとそのモデルは UI スレッドによってアクセスされなくなります (または、バックグラウンド スレッドが実行されないことが確実な場合のみ)。代わりに、チャートの計算とレンダリング全体がバックグラウンド スレッド内でBufferedImage. UI スレッドは、以前にレンダリングされたイメージを画面にブリットするだけでペイントを行います。UI とバックグラウンド スレッド間の更新/同期は、2 つの画像を交換するだけで構成されます。

  4. Lockまたはブロックを使用しsynchronizedて、バックグラウンドと UI スレッドの両方が異なる時間にのみモデルにアクセスするようにします。バックグラウンドの脅威はモデルの更新のみで構成されているため、これは事実上、マルチスレッドがまったくないようなものです。完全を期すためにこのオプションを追加しました…</p>

于 2013-10-25T08:05:04.523 に答える