Reputation: 49
I have page with filter form, a few buttons and big grid. I can search data, based on filter form, and show data in grid. Searching data provides thread, it may take about secs to mins. When I want to click button to stop searching (basically to stop thread), the action is performed always after the thread is done. But I need to perform click event while thread is working. Does somebody know how to do it? :)
UI has @Push(PushMode.MANUAL), and pushing is working fine
Simplified code:
@SpringComponent
@UIScope
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DistraintSearchComponent extends CustomComponent {
@Autowired
private Service service
private Button searchButton = new Button("Search");
private Button stopButton = new Button("Stop");
private Thread searchThread;
public void init(){
searchButton.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
searchThread = new Thread(new Runnable() {
@Override
public void run() {
List<Results> results = service.findByFilter(filter); //this can take some time
refreshGrid(results);
getUI().push();
}
});
searchThread.start();
}
});
stopButton.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
searchThread.interrupt();
}
});
}
}
Thank you
Upvotes: 2
Views: 512
Reputation: 1435
searchThread.interrupt()
does not stop the thread without thread cooperating. From documentation we can see what it does:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
Reason is you cannot stop execution everywhere, that would be a lot of undefined behavior. Instead you should stop your thread in controlled way.
So in your search thread (in your case it would be probably inside service.findByFilter(filter);
) you should be repeatedly checking if thread should end:
while (!Thread.currentThread().isInterrupted()) {
// fetch another entry
}
Documentation also says that you can receive InterruptedException
and ClosedByInterruptException
so you can stop processing when handling this exceptions. ClosedByInterruptException
is IOException
so both exceptions are checked exceptions that have to be handled anyway, but maybe you do not invoke anything that would throw such exception.
try {
Thread.currentThread().sleep(123);
} catch (InterruptedException e) {
return; // return from service.findByFilter(filter);
}
Upvotes: 2