java - 哪里使用线程中断

标签 java multithreading threadpool

我正在使用一些旧代码,并且我对线程不太有经验(主要在前端工作)。不管怎样,这个 Thread.sleep 导致线程挂起,我不确定该怎么办。我考虑过使用计数器并抛出 Thread.currentThread.interupt,但不确定将其放在哪里或它将中断哪个线程。这是转储的示例。正如您所看到的,线程数变得相当高,达到 1708。

有什么建议吗?

"Thread-1708" prio=6 tid=0x2ceec400 nid=0x2018 waiting on condition [0x36cdf000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) Locked ownable synchronizers: - None "Thread-1707" prio=6 tid=0x2d16b800 nid=0x215c waiting on condition [0x36c8f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) Locked ownable synchronizers: - None

@Override
public void run()
{
    Connection con = null;
    int i = 0;

    while (is_running)
    {
        try
        {
            con = ConnectionManager.getConnection();

            while (!stack.isEmpty())
            {
                COUNT++;
                String line = (String) stack.pop();
                getPartMfr(line);
                try
                {
                    if (this.mfr != null && !this.mfr.equals(EMPTY_STR))
                    {
                        lookupPart(con, line);
                    }
                }
                catch (SQLException e)
                {
                    e.printStackTrace();
                }
                if (COUNT % 1000 == 0)
                {
                    Log log = LogFactory.getLog(this.getClass());
                    log.info("Processing Count: " + COUNT);
                }
            }
        }
        catch (NamingException e)
        {
            e.printStackTrace();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                ConnectionManager.close(con);
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
        }


        try {
            Thread.sleep(80);

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    this.finished = true;

}

这里是它调用 run 方法的地方,你可以看到它确实将其设置为 false,但我猜它缺少线程?

    HarrisWorker w[] = new HarrisWorker[WORKER_POOL_SIZE];
    try
    {
        for (int i = 0; i < w.length; i++)
        {
            w[i] = new HarrisWorker(pw);
            w[i].start();
        }
        pw.println(headers());
        File inputDir = new File(HARRIS_BASE);
        String files[] = inputDir.list();
        for (String file : files)
        {

            try
            {
                File f = new File(HARRIS_BASE + File.separator + file);
                if (f.isDirectory())
                    continue;
                final String workFile = workDir + File.separator + file;
                f.renameTo(new File(workFile));

                FileReader fr = new FileReader(workFile);
                BufferedReader br = new BufferedReader(fr);
                String line = br.readLine();

                boolean firstLine = true;

                while (line != null)
                {
                    if (firstLine)
                    {
                        firstLine = false;
                        line = br.readLine();
                        continue;
                    }
                    if (line.startsWith(","))
                    {
                        line = br.readLine();
                        continue;
                    }
                    //          if(line.indexOf("103327-1") == -1)
                    //          {
                    //              line = br.readLine();
                    //              continue;
                    //          }
                    HarrisWorker.stack.push(line);
                    line = br.readLine();
                }
                br.close();
                fr.close();
                for (int i = 0; i < w.length; i++)
                {
                    w[i].is_running = false;

                    while (!w[i].finished)
                    {

                        Thread.sleep(80);   
                    }

                }
                move2Processed(file, workFile);
                long etime = System.currentTimeMillis();
                System.out.println("UNIQUE PARTS TOTAL FOUND: " + HarrisWorker.getFoundCount() + " of " + HarrisWorker.getUniqueCount() + ", "
                        + (HarrisWorker.getFoundCount() / HarrisWorker.getUniqueCount()));
                System.out.println("Time: " + (etime - time));


            }
            catch (Exception e)
            {
                e.printStackTrace();
                File f = new File(workDir + File.separator + file);
                if (f.exists())
                {
                    f.renameTo(new File(HARRIS_BASE + File.separator + ERROR + File.separator + file));
                }

            }
        }
    }

最佳答案

作为对标题中问题的直接回答 - 无处可去。此代码中没有任何地方需要 Thread.interrupt()

线程名称为 Thread-1708 并不一定意味着有 1708 个线程。人们可以为线程选择任意名称。我通常在线程名称中包含执行器或服务的名称。也许有 1600 人现在已经被困住了,只有大约一百人还活着。也许这个特定的类别从 1700 开始命名,以区别于其他用途。

1708个线程可能不是问题。如果您有一个并行服务 2000 个连接的多线程服务器,那么当然可以预期有 2000 个线程以及一堆其他线程在执行此操作。

您必须了解为什么 sleep 存在以及它的目的是什么。它并不是为了无缘无故地占用内存。

将代码转换为“纯文本”(顺便说一句,通过使用 try-with-resources 获取和关闭连接可以大大简化):

  • 获取连接
  • 使用连接发送(我猜)堆栈中的任何内容
  • 失败或完成时 - 等待 80 毫秒(这是您的 sleep )
  • 如果 run 标志仍然设置 - 从步骤 1 开始重复
  • 完成线程。

现在通读本文,显然问题不是 sleep 。这是 run 标志没有设置为 false。并且您的线程只是继续循环,即使它根本无法获得连接 - 它只会花费大部分时间等待重试。事实上 - 即使您完全取消 sleep (而不是中途中断它),您所实现的只是线程将开始使用更多资源。鉴于您有一个记录器并且通过printStackTrace打印到stdout,我想说您有两个问题:

  • 有东西正在生成线程,并且之后没有停止它们(完成后没有将其 run 标志设置为 false)
  • 获取连接时您可能会遇到异常,但您在日志中从未看到它们。

线程可能应该设置它自己的run标志(比如当堆栈被耗尽时),但你必须自己决定 - 这取决于很多细节。

关于java - 哪里使用线程中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28746371/

相关文章:

java - Spring Boot 无法运行依赖于 spring-cloud-starter-config 的 schema.sql

c++ - 如何监控 Qt Signal 事件队列深度

java - Java 中的守护进程线程数

c# - Threadpool is getting used by windows service 问题

c# - IIS 线程无法启动 C#

python-3.x - python并行读取csv文件并连接数据框

java - NoClassDefFoundError : Could not initialize org. hibernate.tool.version

java - 在JTable中添加背景图片

java - 如何以编程方式禁用屏幕锁定密码。

c++ - 使用线程运行服务器时的确切操作顺序