我已经在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中添加元素时,Active线程计数增加的原因。为什么一旦各自的线程完成他们的工作就不会减少它?
当我做错时请告诉我。
答案 0 :(得分:1)
我希望你进行实验,而不是整个代码。从你的代码InvokerServlet
永远不会完成,因为构造函数继续循环。因为,new ThreadInvoker().invokeThreads()
永远不会完成。
如果你想查看执行者的线程数,你应该使用它,并且你的配置数量不会超过 2 。
System.out.println("----> " + ((ThreadPoolExecutor)executor).getActiveCount());
我希望越来越多的线程不是执行程序线程,而是将元素丢弃到队列中的线程。如果您进行线程转储,您将知道这些线程正在做什么以及它们在等待谁。这会给你一个答案,为什么这些线程正在增加。
你没有从队列中出队 - 但是,现在不应该阻止你。它可以添加到计数Integer.MAX_VALUE
答案 1 :(得分:0)
您通过创建新主题ThreadInvoker
和t1
在t2
课程中创建了线程泄漏。你永远不会开始他们,所以他们不能死。
您还会在InvokerServlet
构造函数中进入无限循环。
我的建议:废弃所有代码并寻找有关servlet容器后台任务的正确教程。你并不是第一个想要观察几个队列的人。