这可能是我误读了我所读内容的一种情况,但是在Java中杀死线程的所有示例似乎都表明您必须发出信号以杀死自己。您不能在没有严重风险的情况下从外面杀死它。问题是,所有有关如何“礼貌地”要求线程死亡的示例都有某种循环,因此您要做的就是观察每次迭代中的标志。
因此,我得到的是一个线程,该线程执行的操作仅需要一段时间(一系列SQL查询)。我当然可以在每个步骤之后进行检查,但是它们并没有处于循环中,并且我没有一种非常优雅的方式可以解决此问题。这是我正在做的事的一个例子:
new Thread(new Runnable(){ public void run(){ //query 1 Connection conn = db.getConnection(); Statement s = conn.createStatement(); ResultSet rs = s.executeQuery("SELECT ..."); while(rs.next()){ //do stuff } //query 2 rs = s.executeQuery("SELECT ..."); while(rs.next()){ //do stuff } //query 3 rs = s.executeQuery("SELECT ..."); while(rs.next()){ //do stuff } } }).start();
这是一个示例,我没有使用匿名内部类,但是它说明了我的run()方法无法优雅地停止自身。此外,即使我在每个步骤之后都进行检查,如果特定查询需要很长时间才能运行,则该代码将无法在查询完成后停止。
这段代码是针对GUI应用程序的,我真的很想找到一种无需使用Thread.stop()即可快速杀死线程的好方法。
编辑 -yshavit的回答很有帮助,因为我不知道它的Statement.cancel()存在。如果您感到好奇,那么对我的特定问题的答案是建立一个更抽象的数据库访问类。该类必须创建一个子线程以在运行时执行查询和循环,并检查每次迭代是否当前线程(不是子线程)被中断。如果确实被中断,它将仅调用Statement.cancel(),并且子线程将引发异常并死亡。并非所有的JDBC驱动程序都支持Statement.cancel(),但是Oracle 11g支持。
Statement.cancel()
找出需要一些时间的情况,然后将其取消。如果最耗时的事情是rs.next()循环,则可以执行以下操作:
rs.next()
while(rs.next()){ if (myVolatileBooleanSaysToStop) { return; // or whatever } //do stuff }
如果需要花费一些时间的是语句以及JDBC驱动程序/服务器支持Statement.cancel,那么您可以将您的内容发布Statement到第二个线程,该线程负责进行Statement.cancel适当的调用。我不确定,但是我认为这会导致SQLException驱动程序产生a ,然后您可以以某种方式将其标识为来自取消,并进行相应处理。
Statement.cancel
Statement
SQLException
另外,您应该考虑重构。您可以将三个“运行查询,遍历其结果”的块放入一个方法中(然后将处理关闭该语句等)。