我正在使用一些旧代码,并且我对线程不太有经验(主要在前端工作)。不管怎样,这个 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/