【问题标题】:How can I find My thread in System?如何在系统中找到我的线程?
【发布时间】:2012-01-16 22:26:46
【问题描述】:

我正在编写一个servlet,它必须在init() 中启动一个线程,并在服务器停止后正确停止它。 Thread 下载一个网页,解析它并将数据存储在 MySQL 数据库中。

为了停止线程,我使用 servlet 的 destroy() 方法。在这种方法中,我设置了结束线程的条件。这是正确的做法吗?

我可以在 Windows 的某个地方看到我的线程存在的迹象吗?我在 Windows 任务管理器中没有找到它。

【问题讨论】:

    标签: java multithreading servlets


    【解决方案1】:

    Windows 任务管理器只显示进程,而不是单个线程。事实上,JVM 管理的线程属于用户线程的范畴,与内核线程(由操作系统管理)不同。

    要做你想做的事,你必须保持对Thread 对象的全局引用,这样它就可以在不同的方法中看到。最好让你的线程在一个标志上旋转并通过设置标志来停止它,而不是使用像Thread.stop() 这样的东西。像这样的:

    class ThreadTask implements Runnable {
        private volatile boolean flag = false;
    
        public void setFlag(boolean value) {
            flag = value;
        }
    
        public void run() {
            while(!flag) {
               // execute code
            }
        }
    }
    

    并通过调用setFlag(true) 停止它。

    【讨论】:

    • +1。请注意,Thread.interrupt() 和 family 通常是比 ad hoc volatile 布尔标志更好的选择,因为线程中断允许轻松关闭线程,即使它位于阻塞方法中(很少有例外)。它还可以很好地与许多现有的标准并发实用程序配合使用,例如 ExecutorsFutures。
    • 我这样做了,但是忘记了 volatile 并且没有函数 setFlag。声明为 servlet 字段的标志。
    • 我可以将标志作为 Servlet 类的字段,但不能作为 ThereadTask 的字段。因为我想在 Init() 中声明 ThreadTask。
    • 最好把它放在线程里面,这样线程停止逻辑就不会暴露在外面了。
    【解决方案2】:

    不,您无法在 Windows 中看到它们 - 您在那里看到的是进程,而不是线程。线程在 jvm 进程内部。

    您可以在visualvm 中看到线程(也包含在 JDK/bin/jvisualvm 中)。只需连接到您的 tomcat 并查看线程。

    destroy() 方法是一个不错的选择。但请致电thread.interrupt()

    更好的方法是使用Java 5 executors framework。您创建一个执行程序,并向其提交Runnable。在destroy() 上,您只需拨打executor.shutdown()

    【讨论】:

    • 对不起。如果我只在这个方法中设置标志,为什么会破坏调用中断?
    • 因为线程不应该永远运行。其实tomcat无论如何都会打断它,但是你会得到一个警告
    猜你喜欢
    • 2020-09-05
    • 1970-01-01
    • 2014-02-19
    • 2012-04-19
    • 1970-01-01
    • 2016-07-22
    • 2021-12-25
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多