Multithreading support for JFreeChart
Multithreading support for JFreeChart
Hi all,
I m working on JFree Chart from couple of weeks
Is JFreechart threadsafe?
I have a requirement wherein we will have different schedules running simultaneously and churning out charts more than 1000 charts of different types.
Will there be any issue with this use case.
Thank you
mann
I m working on JFree Chart from couple of weeks
Is JFreechart threadsafe?
I have a requirement wherein we will have different schedules running simultaneously and churning out charts more than 1000 charts of different types.
Will there be any issue with this use case.
Thank you
mann
-
- Posts: 844
- Joined: Fri Oct 13, 2006 9:29 pm
- Location: Sunnyvale, CA
Re: Multithreading support for JFreeChart
Like every Swing application, JFreeChart is not thread-safe.mann wrote:Is JFreechart threadsafe?
Richard West
Design Engineer II
Advanced Micro Devices
Sunnyvale, CA
Design Engineer II
Advanced Micro Devices
Sunnyvale, CA
Hi
Thanks for your reply.As you r saying JFree chart is not thread safe.
But my out put is in the form of images(PNG and JPG)
And i hav created one thread Application where 3 threads parellaly calling three diff types of charts, 200 times and it is working
so is thr any threading issue with image as output
waiting for reply
thanks
mann
Thanks for your reply.As you r saying JFree chart is not thread safe.
But my out put is in the form of images(PNG and JPG)
And i hav created one thread Application where 3 threads parellaly calling three diff types of charts, 200 times and it is working
so is thr any threading issue with image as output
waiting for reply
thanks
mann
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
As long as you operate on each chart and its dataset(s) within a single thread, you shouldn't have any trouble. The problems arise when you try updating a dataset from one thread, while drawing the chart in another thread.
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


-
- Posts: 844
- Joined: Fri Oct 13, 2006 9:29 pm
- Location: Sunnyvale, CA
All Swing applications are inherently multithreaded since the AWT events are handled by a separate thread from the main application thread. This is why people keep getting the ConcurrentModificationException problems when they update their datasets. You are safe as long as the redraw happens after the dataset is updated..david.gilbert wrote:As long as you operate on each chart and its dataset(s) within a single thread, you shouldn't have any trouble. The problems arise when you try updating a dataset from one thread, while drawing the chart in another thread.
Richard West
Design Engineer II
Advanced Micro Devices
Sunnyvale, CA
Design Engineer II
Advanced Micro Devices
Sunnyvale, CA
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Yes, very true. It's wise to use the SwingUtilities.invokeLater() method to wrap code that updates datasets...this ensures that the dataset update doesn't clash with the chart repaint. I need to (a) document this better, and (b) follow this advice in the demo apps (being a lazy programmer, I sometimes cut corners and hope that things won't go wrong).RichardWest wrote:All Swing applications are inherently multithreaded since the AWT events are handled by a separate thread from the main application thread. This is why people keep getting the ConcurrentModificationException problems when they update their datasets. You are safe as long as the redraw happens after the dataset is updated..
I'd actually like to write the required code to synchronise updates without developers having to worry about it - a ReadWriteLock on the dataset ought to work:
http://java.sun.com/javase/6/docs/api/j ... eLock.html
This would get a lot trickier, though, for charts that rely on multiple datasets, since it would require locking a whole group of datasets while the chart repainting was in progress. And here's where I start to wonder if it would end up in a big dead-locked mess...and then I go start working on some different feature!
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


I think adding synchronization to the chart-datasets and the chart rendering system is not a good idea.
(1) Synchronization is expensive. Whenever you access a lock you have a potential context switch, so your code will be slower without any real gain so far. If you implement fine grained locks, then you will pay heavy penalties and users will complain. Implement a coarse grained locking and you will block the caller for a long time, making your program unresponsive and the user complains.
(2) With sane programming, all synchronization issues for a particular chart can be solved by synchronizing against a external lock (and heck, this could even be the "JFreeChart" object itself). At that point, the *user* is responsible for ensuring synchronization and with some simple precautions can avoid synchronization altogether.
However, most users simply have no clue about synchronization and don't want to learn it (or even read the corresponding sections in the Swing-Tutorial). Or as my old teacher always said: "In most cases the problem sits in front of the keyboard"
(1) Synchronization is expensive. Whenever you access a lock you have a potential context switch, so your code will be slower without any real gain so far. If you implement fine grained locks, then you will pay heavy penalties and users will complain. Implement a coarse grained locking and you will block the caller for a long time, making your program unresponsive and the user complains.
(2) With sane programming, all synchronization issues for a particular chart can be solved by synchronizing against a external lock (and heck, this could even be the "JFreeChart" object itself). At that point, the *user* is responsible for ensuring synchronization and with some simple precautions can avoid synchronization altogether.
However, most users simply have no clue about synchronization and don't want to learn it (or even read the corresponding sections in the Swing-Tutorial). Or as my old teacher always said: "In most cases the problem sits in front of the keyboard"

-
- Posts: 844
- Joined: Fri Oct 13, 2006 9:29 pm
- Location: Sunnyvale, CA
Re: Multithreading support for JFreeChart
I faced ConcurrentModificationException even in single thread, for large amount of data which arrives too fast.
I solved as below:
-------------------------------------
public class PlottingThread implements /*Runnable,*/ ChartProgressListener { // Runnable if you wish separate thread, both are working for me
public void doInit() {
my_jfreechart_object.addProgressListener(this);
}
/*
public void run() { // If threaded
plotData();
}
*/
public synchronized void plotData() {
For(....) {
// plot your data here
try {
this.wait();
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
}
}
private synchronized void doNotification() {
this.notifyAll();
}
public void chartProgress(ChartProgressEvent pe) {
if(pe.getType() == ChartProgressEvent.DRAWING_FINISHED) {
doNotification();
}
}
}
----------------------------
GB
I solved as below:
-------------------------------------
public class PlottingThread implements /*Runnable,*/ ChartProgressListener { // Runnable if you wish separate thread, both are working for me
public void doInit() {
my_jfreechart_object.addProgressListener(this);
}
/*
public void run() { // If threaded
plotData();
}
*/
public synchronized void plotData() {
For(....) {
// plot your data here
try {
this.wait();
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
}
}
private synchronized void doNotification() {
this.notifyAll();
}
public void chartProgress(ChartProgressEvent pe) {
if(pe.getType() == ChartProgressEvent.DRAWING_FINISHED) {
doNotification();
}
}
}
----------------------------
GB
Re: Multithreading support for JFreeChart
A better solution is to update the information in the Swing thread. The following works and is significantly simpler...
Code: Select all
void add(final double value) {
final Millisecond time = new Millisecond();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
series.add(time, value, true);
}
});
}