在 ExecuterService 中使用线程的 isAlive(),Interrupt() 和 stop() 方法的问



我发现isAlive((方法在使用ExecuterService执行线程时不起作用。 中断(( 和 stop(( 方法也不起作用。
我使用的代码:

Thread t1=new Thread(()->{
try{
Thread.sleep(10000);
} catch(InterruptedExeception ie){
System.out.println("Interrupted");
}
Thread.sleep(5000);
System.out.println("It's Done");
});
ExecuterService excuter=Executers.newSingleThreadExecuter();
excuter.execute(t1);
Thread.sleep(2000);
System.out.println(t1.isAlive());
Thread.sleep(2000);
t1.interrupt();
t1.stop();

我的预期输出是:

真正的
中断

实际输出为:


的 它完成了

我需要这种行为的理由。我想知道这个问题的解决方案是什么,以及当线程在线程池中运行时我如何使用这些方法。

  1. stop()方法不起作用。你不能像这样停止线程。线程需要选择允许自己停止;例如,您将更新一个(易失性或原子布尔样式(布尔值,线程运行一个循环,并在每个循环上检查该布尔值;如果它是假的,它就结束了。没有办法阻止其轨道中的任意线程。完全。你可以谷歌搜索为什么 Thread.stop 被弃用的信息(并且实际上不再起作用,即使该方法仍然存在,主要是作为文档的工具,为什么你不能再这样做了(。

  2. 线程
  3. 实现可运行,这就是为什么您甚至可以将该线程传递给执行器方法,但根本没有使用整个线程基础结构。您应该将此代码更新为 Runnable r = (( -> { ... } 并传递它。您编写的代码会误导您认为这是正在运行的线程。不是,这就是为什么你会.isAlive()false.

  4. 执行者通常不会暴露他们做工作的方式,他们只是这样做。如果要检查作业是否正在运行,请在进入时将(易失性或原子布尔值(布尔值设置为 true,在退出时设置为 false。或者,如果您真的想使用线程功能,例如.isAlive(),请不要为执行器服务而烦恼,只需启动您的线程即可。

t1

不是线程。

t1是一个Thread实例,但Thread实例与线程不同,并且您使用t1的方式,永远不会创建线程。将Thread实例视为用于创建和控制线程的句柄。 如果您的程序调用t1.start(),则将创建线程,然后t1.isAlive()t1.interrupt()以及t1.stop()调用都将在该新线程上运行。

除了是Thread实例之外,t1也恰好是一个Runnable实例,这正是executer.execute(...)调用所想要的。成为Runnable只是意味着t1有一个run()方法。 有多种方法可以调用run()方法:

  • 您可以启动线程,t1.start(),在这种情况下,新线程将调用它,
  • 你可以(你确实(把它交给一个Executor.执行此操作时,执行程序会安排其工作线程之一调用run()方法。
  • 您可以简单地调用它 -t1.run()- 这与调用代码定义的任何其他方法没有什么不同。
  • 您可以将其传递给任何其他需要Runnable的库方法。(我不知道有多少,也许很多。

如果要在代码可以控制的线程中调用t1.run(),请调用t1.start()来创建该线程。 如果您希望它由执行程序服务调用,而您不应尝试控制其线程,请执行您所做的操作:调用excuter.execute(t1);

只是不要两者兼而有之。这可能不是你想要的。


P.S.,如果你想继续使用执行者服务,那么你可能应该改变你的t1声明。由于在这种情况下它只需要是一个Runnable,因此您可以编写:

Thread t1=new Runnable(()->{
...
});

这样,阅读您的代码的人就不会挠头并怀疑您是否知道自己在做什么。

最新更新