这可能表明存在编码问题。代码等待FutureTask
尚未执行的 a 的完成。
在下面找到演示片段
未来.java
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
public class Future {
public static void main(String[] args) throws Exception {
FutureTask<String> future = new FutureTask<>(
new Callable<String>() {
@Override
public String call() throws InterruptedException {
return "foo";
}
});
String get = future.get(30, TimeUnit.SECONDS);
System.out.println("get = " + get);
}
}
在会话 1 中运行
javac Future.java
java Future
在会话 2 中运行
$ jps
...
12345 Future
jstack -l 12345 > jstack.12345.log
注意: 是正在运行的进程12345
的PIDjava Future
jstack.12345.log 的内容
"main" #1 prio=5 os_prio=0 tid=0x000000000273b000 nid=0x2b24 waiting on condition [0x0000000002abf000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000781973910> (a java.util.concurrent.FutureTask)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:426)
at java.util.concurrent.FutureTask.get(FutureTask.java:204)
at Future.main(Future.java:19)
编辑根据发布的代码片段,所描述的情况很容易发生。参考Executor.execute的javadoc
在将来的某个时间执行给定的命令。
at some time in the future
这意味着不是立即调用execute
. 因此,您可能会task.get(...)
在任务实际执行之前到达该行。您的线程池也可能无法同时运行numberOfThreads()
线程。
一个演示的小例子(运行与前面描述的相同的命令)。我们创建了一个线程池,它一次只执行一个任务。我们为该池分配了两个任务。在调用executor.execute(..)
这两个任务后,我们立即等待第二个任务的结果。由于第一项任务是一项长期运行的任务,我们将进入您发现的情况。
未来.java
public class Future {
public static void main(String[] args) throws Exception {
FutureTask<String> future1 = new FutureTask<>(
() -> {
System.out.println("future1");
TimeUnit.SECONDS.sleep(50);
return "finished future1";
});
FutureTask<String> future2 = new FutureTask<>(
() -> {
System.out.println("future2");
return "finished future2";
});
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(future1);
executor.execute(future2);
String get = future2.get(30, TimeUnit.SECONDS);
}
}
jstack.12345.log 的内容
"pool-1-thread-1" #9 prio=5 os_prio=0 tid=0x00007ff50811c000 nid=0x5a5c waiting on condition [0x00007ff4e7365000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at concurrent.Future$1.call(Future.java:19)
at concurrent.Future$1.call(Future.java:15)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
"main" #1 prio=5 os_prio=0 tid=0x00007ff50800a000 nid=0x5a4d waiting on condition [0x00007ff50e314000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000ec03dda8> (a java.util.concurrent.FutureTask)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:426)
at java.util.concurrent.FutureTask.get(FutureTask.java:204)
at concurrent.Future.main(Future.java:36)
pool-1-thread-1
- 是future1
当前休眠的转储(模拟长时间运行的任务)
main
- 是 的转储future2.get(30, TimeUnit.SECONDS)
,它等待future2
实际上尚未开始的结果。