你能?
是的,但只使用内部类。创建 cfthread 时,使用本地 THREAD_NAME 检索对底层线程对象的引用。
context = getPageContext().getFusionContext();
thread = context.getUserThreadTask( "theLocalTaskName" );
由于本地名称可以被多个请求使用,所以引用应该存储在一个唯一的名称下,如 uuid。引用实际上是一个内部类的实例coldfusion.threads.Task
。要终止它,请调用它的cancel()
方法。
thread.cancel();
你应该?
这是一个大问题,完全取决于线程做什么——它是如何做的——以及如果进程在中途停止而没有任何警告,它使用的资源将如何受到影响。
原因是调用<cfthread action="terminate"..>
会立即杀死线程。CF 不在乎它是否在关键部分的中间。服务器只是用木槌敲打它并让它变冷。异常日志显示 CF 通过调用Thread.stop()来执行此操作
"Information","cfthread-47","09/07/19","17:10:44","","THREAD_V_2: Terminated"
java.lang.ThreadDeath
at java.base/java.lang.Thread.stop(Thread.java:942)
at coldfusion.thread.Task.cancel(Task.java:257)
at coldfusion.tagext.lang.ThreadTag.terminateThread(ThreadTag.java:345)
at coldfusion.tagext.lang.ThreadTag.doStartTag(ThreadTag.java:204)
java文档说stop()
方法已被弃用,因为它本质上是不安全的:
停止线程会导致它解锁所有已锁定的监视器。(当 ThreadDeath 异常向上传播堆栈时,监视器被解锁。)如果以前受这些监视器保护的任何对象处于不一致状态,则其他线程现在可能会查看这些处于不一致状态的对象。据说这些物体已损坏。当线程对损坏的对象进行操作时,可能会导致任意行为。这种行为可能很微妙且难以检测,也可能很明显。与其他未经检查的异常不同,ThreadDeath 以静默方式杀死线程;因此,用户没有警告他的程序可能已损坏。损坏可以在实际损坏发生后的任何时间出现,甚至在未来几小时或几天内。
因此,重要的是要考虑线程的实际作用,并确定它是否可以安全终止。例如,如果线程使用FileOpen()处理文件,强制终止它可能会阻止线程释放句柄,从而使底层文件处于锁定状态,这是不可取的。
在java中停止线程的推荐方法是使用interrupt()。这本质上就是user12031119 描述的概念。中断不会强行终止线程。这只是一个表明线程停止处理的标志。将其留给线程本身来确定何时可以安全退出。这允许线程在终止之前完成关键部分或执行任何清理任务。是的,它需要更多的编码,但结果比“终止”更稳定和可预测。