使用contextDestroyed干预长时间运行的线程

时间:2012-02-22 13:37:40

标签: java multithreading tomcat

我需要显示一些代码来解释我的问题。

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ServletContextAttribListener implements ServletContextListener
{
private ServletContext context = null;
private MyThread myThread = new MyThread(true);

// This method is invoked when the Web Application
// is ready to service requests

public void contextInitialized(ServletContextEvent event)
{
    this.context = event.getServletContext();
    // Output a simple message to the server's console
    myThread.start();
    System.out.println("The Simple Web App. Is Ready");
}

public void contextDestroyed(ServletContextEvent event)
{
    // Output a simple message to the server's console
    System.out.println("The Simple Web App. Has Been Removed");
    myThread.setB(false);
    this.context = null;
}

public class MyThread extends Thread
{
    private boolean b;

    public MyThread(boolean b)
    {
        this.b = b;
    }

    @Override
    public void run()
    {
        int i = 0;
        int j = 0;
        while (b)
        {
            //This part is important
            for (i = 0; i < 1000000; i++)
            {
            }
            //
            j++;
        }
        System.out.println("Thread stopped i:->" + i + " j:->" + j);
    }

    public boolean isB()
    {
        return b;
    }

    public void setB(boolean b)
    {
        this.b = b;
    }
}
}

正如你所看到的,这是一个非常小的虚拟程序。我没有写web.xml,我只是使用了listener-class。 当我部署war,启动和停止tomcat时,程序的输出是:

The Simple Web App. Is Ready
The Simple Web App. Has Been Removed
Thread stopped i:->1000000 j:->17296

正如你所看到的,我在for循环中是1000000。我想要的是打破循环,无论我是1000000还是小于。

你可以说我可以在 i&lt; 1000000 中使用 b 条件进行for循环,但在我的真实程序中我没有那个for循环。我只是像这里有一个while循环,但其中有许多代码行。我不想每次都检查 b

顺便说一句,我不能使用睡眠/中断。

2 个答案:

答案 0 :(得分:1)

没有此线程的协作,没有干净的方法来阻止线程。因此,如果您需要尽快停止,则必须尽可能经常检查停止标记(示例中为b)。

BTW,b标志应为volatile,否则您的主题可能永远不会停止。

答案 1 :(得分:0)

当上下文被破坏时,不要忘记加入线程。