为什么Future.get(...)没有杀死线程?

时间:2017-11-17 08:07:44

标签: java multithreading apache-kafka

我有一个正在使用future进行异步执行的应用程序 我在get方法上设置了参数,该线程应该在10秒后被杀死,当它没有得到响应时:

 Future<RecordMetadata> meta = producer.send(record, new ProducerCallBack());
      RecordMetadata data = meta.get(10, TimeUnit.SECONDS);  

但该线程在60秒后被杀死:

java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.
    at org.apache.kafka.clients.producer.KafkaProducer$FutureFailure.<init>(KafkaProducer.java:1124)
    at org.apache.kafka.clients.producer.KafkaProducer.doSend(KafkaProducer.java:823)
    at org.apache.kafka.clients.producer.KafkaProducer.send(KafkaProducer.java:760)
    at io.khinkali.KafkaProducerClient.main(KafkaProducerClient.java:49)
Caused by: org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.

我做错了什么?

2 个答案:

答案 0 :(得分:2)

来自docs

  

阻止时间的阈值由max.block.ms确定   它会抛出一个TimeoutException。

在logback.xml中检查Kafka Appender配置,查找:

<producerConfig>max.block.ms=60000</producerConfig>

答案 1 :(得分:1)

  

我在get方法上设置了参数,该线程应该在10秒后被杀死,当它没有得到响应时:

如果我们谈论的是Future.get(...),那么就没有任何事情可以解决这个问题。线程根本。引用javadocsFuture.get(...)方法:

  

如果需要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。

如果get(...)方法超时则会抛出TimeoutException,但您的线程可以继续运行。如果你想阻止线程运行,那么你需要捕获TimeoutException,然后调用meta.cancel(true),但即使这样也不能保证该线程将被杀死#&#34} 34 ;.这会导致线程被中断,这意味着certain methods will throw InterruptedException或线程需要检查Thread.currentThread().isInterrupted()

  

java.util.concurrent.ExecutionException:org.apache.kafka.common.errors.TimeoutException:60000毫秒后无法更新元数据。

是的,此超时与Future.get(...)超时无关。