我的页面带有过滤器表单,一些按钮和大网格。我可以根据过滤器形式搜索数据,并在网格中显示数据。搜索数据提供了线程,可能需要花费数秒至数分钟的时间。当我想单击按钮停止搜索(基本上是停止线程)时,操作总是在线程完成之后执行。但是我需要在线程工作时执行click事件。有人知道该怎么做吗? :)
UI具有@Push(PushMode.MANUAL),并且推送工作正常
简化代码:
@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();
}
});
}
}
谢谢
答案 0 :(得分:2)
searchThread.interrupt()
不会在没有线程合作的情况下停止线程。从documentation我们可以看到它的作用:
如果在调用Object类的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long)时阻塞了此线程,int),sleep(long)或sleep(long,int)这类方法,则其中断状态将被清除,并且将收到InterruptedException。
如果此线程在可中断通道上被I / O操作阻塞,则该通道将关闭,该线程的中断状态将被设置,并且该线程将收到ClosedByInterruptException。
如果该线程在选择器中被阻塞,则该线程的中断状态将被设置,并且它将立即从选择操作中返回,可能具有非零值,就像调用选择器的唤醒方法一样。
如果以上条件均不成立,则将设置此线程的中断状态。
原因是您无法在任何地方停止执行,这将是很多未定义的行为。相反,您应该以受控方式停止线程。
因此,在您的搜索线程中(就您而言,它可能位于service.findByFilter(filter);
内),您应该反复检查线程是否应结束:
while (!Thread.currentThread().isInterrupted()) {
// fetch another entry
}
文档还说您可以收到InterruptedException
和ClosedByInterruptException
,因此在处理此异常时可以停止处理。 ClosedByInterruptException
是IOException
,因此这两个异常都是经过检查的异常,无论如何都必须处理它们,但是也许您不调用任何会引发此类异常的东西。
try {
Thread.currentThread().sleep(123);
} catch (InterruptedException e) {
return; // return from service.findByFilter(filter);
}