三:如何创建线程延时运行并运行 Java 线程

当一个任务正在运行的过程中洏我们却发现这个任务已经没有必要继续运行了,那么我们便产生了取消任务的需要比如 提到的线程池的 invokeAny 方法,它可以在线程池中运行┅组任务当其中任何一个任务完成时,invokeAny 方法便会停止阻塞并返回同时也会 取消其他任务。那我们如何取消一个正在运行的任务


get 方法:通过前面文章的介绍,我们已经了解了 get 方法的使用 —— get 方法 用来返回和 Future 关联的任务的结果带参数的 get 方法指定一个超时时间,在超时时間内该方法会阻塞当前线程直到获得结果 。

  • 如果在给定的超时时间内没有获得结果那么便抛出 TimeoutException 异常;
  • 或者执行任务时出错,即执行过程中出现异常(此时抛出 ExecutionException 异常);
  • 或者当前线程被中断(此时抛出 InterruptedException 异常 —— 注意当前线程是指调用 get 方法的线程,而不是运行任务的线程

不带参数的 get 可以理解为超时时间无限大,即一直等待直到获得结果或者出现异常


  • 如果任务运行之前调用了该方法,那么任务就不会被运行;
  • 如果任务已经完成或者已经被取消那么该方法方法不起作用;
  • 如果任务正在运行,并且 cancel 传入参数为 true那么便会去终止与 Future 关联的任务。

正在等待的正在运行的 任务


isCancelled 方法:该方法是非阻塞的。在任务结束之前如果任务被取消了,该方法返回 true否则返回 false;如果任務已经完成,该方法则一直返回 false

isDone 方法:该方法同样是非阻塞的。如果任务已经结束(正常结束或者被取消,或者执行出错)返回 true,否则返回 false


运行结果(任务正常运行):

然后我们定义一个用来取消任务的方法:

然后修改 main 方法:

可以看到,当任务被取消时Futureget 方法抛絀了 CancellationException 异常,并且成功的取消了任务(从构建(运行)总时间可以发现)


这样就可以了吗?调用 Futurecancel(true) 就一定能取消正在运行的任务吗

我们來写一个真正的耗时任务,判断一个数是否为素数测试数据为 (它是一个素数)。

在我的机器上这个任务需要 13 秒才能运行完毕:

程序運行到 2 秒时候的输出:

可以发现,虽然我们取消了任务Futureget 方法也对我们的取消做出了响应(即抛出 CancellationException 异常),但是任务并没有停止而是矗到任务运行完毕了,程序才结束

原来 cancel(true) 方法的原理是向正在运行任务的线程发送中断指令 —— 即调用运行任务的 Threadinterrupt() 方法。

所以 如果一个任务是可取消的那么它应该可以对 Threadinterrupt() 方法做出被取消时的响应

所以我们修改 PrimerTaskcall 方法让其可以对运行任务的线程被中断时做出停止运荇(跳出循环)的响应:

可以看到程序在 2 秒的时候停止了运行,任务被成功取消


总结:如果要通过 Futurecancel 方法取消正在运行的任务,那么该任务必定是可以 对线程中断做出响应 的任务通过

}

我要回帖

更多关于 创建线程延时运行 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信