0

我正在尝试在 Java 中实现一个缓存线程池来读取来自总线的数据。一切都很好......只要我在那辆公共汽车上有数据。

如果我断开数据线,程序开始从池中生成无限线程。我间歇性地检查 /proc/{PID}/fd 并在大约一个小时内从 8 变为 100+。最终系统崩溃。

我正在为这些线程(30 秒)提交超时值,它们确实触发了我在日志文件中看到的 TimeoutException Catch。这些线程不应该在超时时结束吗?

一些代码:

private static ExecutorService executorService = Executors.newCachedThreadPool();

(我后来提供了一个可调用的)

long[] rawFrame;
Future<long[]> future = executorService.submit(callable);
try {
    rawFrame = future.get(timeout, timeUnit); // timeout is 30 seconds
    // Do some things with the raw frame and store as parsedFrame
    return parsedFrame;
} catch (TimeoutException e) {
    LOGGER.error("Bus timeout. Check connection");
    return null;
} finally {
    future.cancel(true);
}

我只是在学习如何在 Java 中进行并发处理,但据我所知,这些进程应该超时,但看起来他们只是坐在那里等待总线上没有数据的数据。

我错过了什么?

编辑:感谢您帮助我缩小范围。

这是我的可调用对象

private class BusCallable implements Callable<long[]> {

private long messageId;
private boolean readAnyFrame = false;

public BusCallable() {
    super();
    readAnyFrame = true;
}

public BusCallable(long id) {
    super();
    this.messageId = id;
    readAnyFrame = false;
}

@Override
public long[] call() throws Exception() {
    if (readAnyFrame) {
        return read(busInterface);
    }
    return readFrame(busInterface, messageId);
 }
4

1 回答 1

1

使用超时调用 Future.get() 将使 get() 超时,而不是线程超时(即,whataver 在可调用的 call() 方法中)。如果您的可调用对象没有结束,它将保留在服务中,并且如果您继续添加更多可调用对象将累积。您应该在可调用的线程中设置超时机制。

于 2014-05-09T20:11:46.593 回答