I have a Java application that processes a stream of data from data coming in through a serial port and displays a summary in the Swing user interface.
It works fine, but when I set breakpoints in Eclipse in specific threads (like a Swing event dispatch thread), I have a limited amount of time before the JVM scans to a stop: incoming data is still being processed and some system queue, whether The data queue or event queue is full.
Is there any way to detect this in upstream threads so that my thread processing starts discarding data during debugging?
If my program explicitly uses the queue, I can just throw out the data when the queue size becomes too high.
But I cannot do this if the queue is "implicit", for example. it was controlled by some other software that was beyond my direct control. I can imagine two possibilities:
If I use SwingUtilities.invokeLater()either another user interface structure that calls SwingUtilities.invokeLater (), how can I detect a backup of the event stream with events?
If I use ExecutorService.submit(), how can I determine if there will be a backup of the executor's task queue?
update: I think I decided # 2 by wrapping my ExecutorService:
AbstractPipelineExecutor.java:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
abstract public class AbstractPipelineExecutor {
public interface Task extends Runnable
{
public void denied();
}
final private ExecutorService executor;
public AbstractPipelineExecutor(ExecutorService executor)
{
this.executor = executor;
}
public Future<?> submit(final Task task)
{
Future<?> result = null;
if (this.executor.isShutdown())
{
task.denied();
}
else
{
try
{
onSubmit(task);
result = this.executor.submit(new Runnable() {
@Override public void run()
{
onBeginExecute(task);
try
{
task.run();
}
catch (RuntimeException e)
{
onExecutionException(task, e);
}
finally
{
onEndExecute(task);
}
}
});
}
catch (RejectedExecutionException e)
{
task.denied();
}
}
return result;
}
abstract protected void onSubmit(Task task) throws RejectedExecutionException;
protected void onBeginExecute(Task task) {}
protected void onExecutionException(Task task, RuntimeException e) {
throw(e);
}
protected void onEndExecute(Task task) {}
}
BoundedPipelineExecutor.java:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
public class BoundedPipelineExecutor extends AbstractPipelineExecutor {
public BoundedPipelineExecutor(ExecutorService executor, int bound) {
super(executor);
this.q = new ArrayBlockingQueue<Task>(bound);
}
final private ArrayBlockingQueue<Task> q;
@Override public void onSubmit(Task task)
{
if (!this.q.offer(task))
throw new RejectedExecutionException(task.toString());
}
@Override public void onBeginExecute(Task task)
{
this.q.remove();
}
}
source
share