【问题标题】:Tomcat thread count gets increased onlyTomcat 线程数只会增加
【发布时间】:2015-08-04 06:03:27
【问题描述】:

我已经使用托管在 Tomcat 7 上的 JSP-Servlet 创建了简单的 Web 应用程序。根据我的要求,我需要创建 2 个后台线程,它们将在一段时间内不断检查它们各自的共享队列,以及是否在它们的它将处理该元素的各个队列。

对于这2个连续线程管理,我使用了java.util.concurrent.Executors。它对我来说很好,但问题是, java.lang.Thread.activeCount() 只有当我执行一些操作以在资源队列中添加元素时才会增加。此外,当我检查 Java VisualVM 时,它显示线程数不断增加。

以下是我的代码段:

Web.xml:

<servlet>
        <servlet-name>InvokerServlet</servlet-name>
        <display-name>InvokerServlet</display-name>
        <description></description>
        <servlet-class>com.test.servlet.InvokerServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

这是在tomcat启动时启动我的InvokerServlet,它将启动线程:

InvokerServlet.java:

public class InvokerServlet extends HttpServlet {
    Logger log = Logger.getLogger(InvokerServlet.class);
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public InvokerServlet() {
        super();
        log.debug("Initiate thread invoking");
        new ThreadInvoker().invokeThreads();
    }
...
...
}

ThreadInvoker.java:

public class ThreadInvoker 
{
    Thread1 t1 = new Thread1();
    Thread2 t2 = new Thread2();

    public static Queue queue1 = new LinkedBlockingQueue();
    public static Queue queue2 = new LinkedBlockingQueue();

    private static ExecutorService executor = null;
    private static volatile Future result1= null;
    private static volatile Future result2 = null;

    public void invokeThreads()
    {
        executor = Executors.newFixedThreadPool(2);

        while (true)
        {
            System.out.println("----> " + java.lang.Thread.activeCount());
            try
            {
                checkTasks();
                Thread.sleep(1000);
            } catch (Exception e) {
                System.err.println("Caught exception: " + e.getMessage());
            }
        }
    }

    private void checkTasks() throws Exception
    {
        if(queue1.size() > 0)
        {
            result1 = executor.submit(t1);
        }

        if(queue2.size() > 0)
        {
            result2 = executor.submit(t2);
        }
    }
}

Thread1.java

public class Thread1 implements Runnable
{

    public void run() 
    {
        try
        {
            log.debug("Inside Thread1 run");
            Thread.sleep(2000);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

Thread2.java

public class Thread2 implements Runnable
{

    public void run() 
    {
        try
        {
            log.debug("Inside Thread2 run");
            Thread.sleep(2000);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

所以我的问题是为什么当我通过一些外部操作在 queue1 和 queue2 中添加元素时活动线程计数会增加。为什么他们各自的线程完成工作后它不会减少?

如果我做错了,请告诉我。

【问题讨论】:

  • 使用线程池。它已经在做你想要重塑的事情。

标签: java multithreading tomcat threadpoolexecutor


【解决方案1】:

我希望您正在试验,而这并不是全部代码。从您的代码中,InvokerServlet 将永远不会完成,因为构造函数会继续进行无休止的 while 循环。因为,new ThreadInvoker().invokeThreads() 永远不会结束。

如果您只想查看执行程序的线程数,您应该使用它,并且计数不会增加超过您配置的 2

System.out.println("----> " + ((ThreadPoolExecutor)executor).getActiveCount());

我希望越来越多的线程不是执行线程,而是将元素放入队列的线程。如果您进行线程转储,您将知道这些线程在做什么以及它们在等待谁。这会给你一个答案,为什么这些线程在增加。

您没有从队列中出队 - 但是,现在不应该阻止您。它可以一直持续到您添加计数 Integer.MAX_VALUE

的元素

【讨论】:

  • 感谢您的指导。我已经检查了您提供的代码及其仅使用 0 到 2 之间的线程数:)。对于 InvokerServlet,是的,它不允许启动我的服务器,所以我也更新了该代码。再次感谢:)
【解决方案2】:

您正在通过创建新线程t1t2ThreadInvoker 类中创建线程泄漏。你永远不会启动它们,所以它们不会死。

您还将在 InvokerServlet 构造函数中进入无限循环。

我的建议:放弃所有代码并寻找有关 servlet 容器后台任务的适当教程。你不是第一个想要观察几个队列的人。

【讨论】:

    猜你喜欢
    • 2011-09-18
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 2015-05-03
    • 2017-06-29
    • 1970-01-01
    相关资源
    最近更新 更多