2014-03-03 36 views
0

我試圖在線監視一組計算機資源。爲了做到這一點,我使用JFreechart並嘗試使用多線程來獲得性能。JFreeChart中的多線程

這裏是我的代碼:

class osGenel extends JPanel implements Runnable { 
    String name; 
    private static DefaultValueDataset[] DATASET; 
    Integer VALUE,iii,sayac; 
    Thread t; 

    private static Sessionn[] obj; 
    osGenel(String s,DefaultValueDataset valuedataset,Double n,Double w,Double c,int i) { 
     name = s; 
     iii=i; 
     t = new Thread(this, name); 
     this.setLayout(new GridLayout()); 
     DATASET[iii]=valuedataset; 
     MeterPlot meterplot = new MeterPlot(DATASET[iii]); 
     meterplot.setDialShape(DialShape.CIRCLE); 
     meterplot.setRange(new Range(0.0D, 100D)); 
     meterplot.addInterval(new MeterInterval("Normal", new Range(0.0D, n), Color.lightGray, new BasicStroke(2.0F),Color.GREEN)); 
     meterplot.addInterval(new MeterInterval("Warning", new Range(n, w), Color.lightGray, new BasicStroke(2.0F), Color.YELLOW)); 
     meterplot.addInterval(new MeterInterval("Critical", new Range(w, c), Color.lightGray, new BasicStroke(2.0F), Color.RED)); 

     meterplot.setNeedlePaint(Color.darkGray); 
     meterplot.setDialBackgroundPaint(Color.white); 
     meterplot.setDialOutlinePaint(Color.gray); 
     meterplot.setMeterAngle(260); 
     meterplot.setTickLabelsVisible(true); 
     meterplot.setTickLabelFont(new Font("Dialog", 1,25)); 
     meterplot.setTickLabelPaint(Color.darkGray); 
     meterplot.setTickSize(5D); 
     meterplot.setBackgroundPaint(Color.black); 
     meterplot.setTickPaint(Color.lightGray); 
     meterplot.setValuePaint(Color.black); 
     meterplot.setValueFont(new Font("Dialog", 1, 0)); 

     JFreeChart chart = new JFreeChart(s, JFreeChart.DEFAULT_TITLE_FONT, meterplot, true); 
     this.add(new ChartPanel(chart, false)); 
     t.start(); 
    } 
    public void run() { 
     try { 

      for (int i = 100; i > 0; i--) { 
       System.out.println(iii + ". Thread running"); 
       Random r=new Random(); 

       DATASET[iii].setValue(r.nextInt(100)); 
       Thread.sleep(3000); 
      } 
     } catch (InterruptedException e) { 
      System.out.println(name + "Interrupted"); 
     } 
     System.out.println(name + " Out."); 
    } 

    public static void main(String args[]) 
    { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       DefaultValueDataset defaultvaluedataset = new DefaultValueDataset(23D); 
       final JFrame f = new JFrame("OS MONITOR"); 
       f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       obj=new Sessionn[9]; 
       DATASET=new DefaultValueDataset[9]; 
       f.setLayout(new GridLayout(3, 3)); 
       f.add(new osGenel("CPU", defaultvaluedataset,60D,90D,100D,0)); 
       f.add(new osGenel("DISK", defaultvaluedataset,60D,90D,100D,1)); 
       f.add(new osGenel("MEMORY", defaultvaluedataset,60D,90D,100D,2)); 
       f.add(new osGenel("CPU", defaultvaluedataset,60D,90D,100D,3)); 
       f.add(new osGenel("DISK", defaultvaluedataset,60D,90D,100D,4)); 
       f.add(new osGenel("MEMORY", defaultvaluedataset,60D,90D,100D,5)); 
       f.add(new osGenel("CPU", defaultvaluedataset,60D,90D,100D,6)); 
       f.add(new osGenel("DISK", defaultvaluedataset,60D,90D,100D,7)); 
       f.add(new osGenel("MEMORY", defaultvaluedataset,60D,90D,100D,8)); 
       f.pack(); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 

的問題是,當我運行這個程序,我的線程工作,在每個線程有不同的價值,但我的數據集總是從這些線程相同的值。我認爲我的每個數據集都會得到不同的值,但它不會。所有圖表顯示每個線程都有相同的值。

+1

您不應該修改EDT以外的其他線程中的數據集。將新數據存儲到雙數組中並設置髒標誌。調用帶有可運行的'SwingUtilities.invokeLater(..)'來檢查髒標誌並在必要時更新數據集。 – Stephan

+0

我找到了我的解決方案,但你能告訴我關於這個「invokeLater」的例子嗎? – AloneInTheDark

回答

2

您有一個很大的問題,您使用的DefaultValueDataset您的所有線程一個實例,在下面的代碼:

DefaultValueDataset defaultvaluedataset = new DefaultValueDataset(23D); 
f.add(new osGenel("CPU", defaultvaluedataset,60D,90D,100D,0)); 
f.add(new osGenel("DISK", defaultvaluedataset,60D,90D,100D,1)); 
f.add(new osGenel("MEMORY", defaultvaluedataset,60D,90D,100D,2)); 
f.add(new osGenel("CPU", defaultvaluedataset,60D,90D,100D,3)); 
f.add(new osGenel("DISK", defaultvaluedataset,60D,90D,100D,4)); 
f.add(new osGenel("MEMORY", defaultvaluedataset,60D,90D,100D,5)); 
f.add(new osGenel("CPU", defaultvaluedataset,60D,90D,100D,6)); 
f.add(new osGenel("DISK", defaultvaluedataset,60D,90D,100D,7)); 
f.add(new osGenel("MEMORY", defaultvaluedataset,60D,90D,100D,8)); 

正因爲如此,你必須在每個面板相同的結果。

更改該代碼:

f.add(new Test("CPU", new DefaultValueDataset(23D), 60D, 90D, 100D, 0)); 
f.add(new Test("DISK", new DefaultValueDataset(23D), 60D, 90D, 100D, 1)); 
f.add(new Test("MEMORY", new DefaultValueDataset(23D), 60D, 90D, 100D, 2)); 
f.add(new Test("CPU", new DefaultValueDataset(23D), 60D, 90D, 100D, 3)); 
f.add(new Test("DISK", new DefaultValueDataset(23D), 60D, 90D, 100D, 4)); 
f.add(new Test("MEMORY", new DefaultValueDataset(23D), 60D, 90D, 100D, 5)); 
f.add(new Test("CPU", new DefaultValueDataset(23D), 60D, 90D, 100D, 6)); 
f.add(new Test("DISK", new DefaultValueDataset(23D), 60D, 90D, 100D, 7)); 
f.add(new Test("MEMORY", new DefaultValueDataset(23D), 60D, 90D, 100D, 8)); 

,你會看到預期的結果。

2

JFreeChart是一個Swing庫,它是不是線程安全。無論你想達到什麼目的,你都應該更清楚地描述你的意圖,你認爲性能問題來自哪裏,以及你打算如何通過線程提高性能。

然而,所觀察到的行爲的原因如下:

所有DATASET陣列中的DefaultValueDataset實例是相同的。只有一個DefaultValueDataset的實例,並且此實例在數組中存儲9次。

你可以你的初始化更改爲類似

final JFrame f = new JFrame("OS MONITOR"); 
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
obj=new Sessionn[9]; 
DATASET=new DefaultValueDataset[9]; 
for (int i=0; i<DATASET.length) 
{ 
    DATASET[i] = new DefaultValueDataset(23D); 
} 
f.setLayout(new GridLayout(3, 3)); 
f.add(new osGenel("CPU", DATASET[0],60D,90D,100D,0)); 
f.add(new osGenel("DISK", DATASET[1],60D,90D,100D,1)); 
f.add(new osGenel("MEMORY", DATASET[2],60D,90D,100D,2)); 
f.add(new osGenel("CPU", DATASET[3],60D,90D,100D,3)); 
f.add(new osGenel("DISK", DATASET[4],60D,90D,100D,4)); 
f.add(new osGenel("MEMORY", DATASET[5],60D,90D,100D,5)); 
f.add(new osGenel("CPU", DATASET[6],60D,90D,100D,6)); 
f.add(new osGenel("DISK", DATASET[7],60D,90D,100D,7)); 
f.add(new osGenel("MEMORY", DATASET[8],60D,90D,100D,8)); 

但一些進一步的清理工作可能是合適的,並再次:的JFreeChart不是線程安全的!