我发现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();
我的预期输出是:
真正的
中断
实际输出为:
假
的 它完成了
我需要这种行为的理由。我想知道这个问题的解决方案是什么,以及当线程在线程池中运行时我如何使用这些方法。
-
stop()
方法不起作用。你不能像这样停止线程。线程需要选择允许自己停止;例如,您将更新一个(易失性或原子布尔样式(布尔值,线程运行一个循环,并在每个循环上检查该布尔值;如果它是假的,它就结束了。没有办法阻止其轨道中的任意线程。完全。你可以谷歌搜索为什么 Thread.stop 被弃用的信息(并且实际上不再起作用,即使该方法仍然存在,主要是作为文档的工具,为什么你不能再这样做了(。
线程 实现可运行,这就是为什么您甚至可以将该线程传递给执行器方法,但根本没有使用整个线程基础结构。您应该将此代码更新为 Runnable r = (( -> { ... } 并传递它。您编写的代码会误导您认为这是正在运行的线程。不是,这就是为什么你会
.isAlive()
false
.执行者通常不会暴露他们做工作的方式,他们只是这样做。如果要检查作业是否正在运行,请在进入时将(易失性或原子布尔值(布尔值设置为 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(()->{
...
});
这样,阅读您的代码的人就不会挠头并怀疑您是否知道自己在做什么。