Why does my Swingworker cancel its thread only the first time?
I have a Swingworker that I sometimes need to cancel. If I execute and then cancel, it works as expected. If I run a new instance of that Swingworker and then t开发者_如何学运维ry to cancel it, the cancel function is called, it returns true, but the "doInBackground" method runs fully without being cancelled. By fully, I mean the while loop in the the function the Swingworker thread runs completes (which I can cancel only the first time).
Let me know if I made my problem clear, it is such a strange behaviour that I just can't figure out.
Here is my code:
protected void firePlayButtonPlotWorker() {
/*Cancel any previous plotWorker threads that may be running. The user might click the play
* button again, so we ignore that if the thread isn't finished.*/
if(plotWorker != null && !plotWorker.isDone())
{
System.err.println("Cancelling plot thread");
plotWorker.cancel(true);
}
/*Create a SwingWorker so that the computation is not done on the Event Dispatch Thread*/
plotWorker = new SwingWorker<Void, Void>()
{
@Override
public Void doInBackground()
{
System.err.println("Plot Swing Worker Thread starting");
playAudio(sceneManager.getScenes()); //Computation that requires an asynchronous while loop
System.err.println("Plot Swing Worker Thread ended");
return null;
}
@Override
public void done()
{
plotWorker = null;
}
};
plotWorker.execute();
}
public void handleAudioEvent(AudioState audioState)
{
switch (audioState)
{
case PLAY:
firePlayButtonPlotWorker();
break;
case PAUSE:
if(plotWorker != null)
{
boolean cancelBool = plotWorker.cancel(true);
System.out.println("Cancelled? " + cancelBool);
}
break;
case STOP:
if(plotWorker != null)
{
plotWorker.cancel(true);
}
audioPlayerMarkerBean.setMarkerLocation(0);
double[] coord = {0.0, 0.0};
marker.drawMarker(coord);
break;
}
}
Calling cancel with true as argument will interrupt the thread, using the Thread.interrupt method.
So if your thread is waiting, sleeping or joining, an InterruptedException will be thrown. Else, the thread's interrupt status will be set.
If you swallow the InterruptedException, the thread will continue until its end. If the thread is running (i.e. not waiting, sleeping or joining) when it's interrupted, it will continue running as well. You must regularly check the interrupted status of the thread (using Thread.currentThread.isInterrupted()
) in your background task and stop executing as soon as it returns true.
精彩评论