gpt4 book ai didi

java - 使用 Callable 时出现奇怪的调用堆栈

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:44:24 26 4
gpt4 key购买 nike

当使用 Executors 和 callable 从调用中转储调用堆栈时,我看到了奇怪的结果。来自可调用对象的方法在调用堆栈中出现了两次。

pool-1-thread-1@454, prio=5, in group 'main', status: 'RUNNING'
at com.test.tracked.ACallable.call(ACallable.java:15)
at com.test.tracked.ACallable.call(ACallable.java:9)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

可以看到,方法ACallable在栈中出现了两次:第9行是ACallable类的声明,第15行是方法签名:

package com.test.tracked;

import java.util.concurrent.Callable;

/**
* A callable test class.
*
*/
public final class ACallable
implements Callable<String> {
private final String who;

@Override
public String call() throws Exception {
Thread.dumpStack();
return "Hello "+who+" from callable";
}

public ACallable(String who) {
this.who = who;
}

}

“主”线程:

main@1, prio=5, in group 'main', status: 'WAIT'
at sun.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:994)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1303)
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:248)
at java.util.concurrent.FutureTask.get(FutureTask.java:111)
at com.test.tracked.AsynchronousCall.callFuture(AsynchronousCall.java:26)
at com.test.Main.main(Main.java:21)

调用可调用对象的代码:

package com.test.tracked;

import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;



/**
* Aynchronous call
*/
public class AsynchronousCall implements Closeable {

private final ExecutorService executorService;


public AsynchronousCall() {
executorService = Executors.newSingleThreadExecutor();
}

public String callFuture(String who) throws InterruptedException, ExecutionException, TimeoutException {
Thread.dumpStack();
String ret = executorService.submit(new ACallable(who)).get();
System.out.println("callFuture from " + getClass().getName() + " return " + ret);
return ret;
}

@Override
public void close() throws IOException {
executorService.shutdownNow();
}
}

最佳答案

编译器添加了一个合成桥接方法来支持泛型。所以

@Override
public String call() throws Exception {
Thread.dumpStack();
return "Hello "+who+" from callable";
}

编译后的.class文件中真的是两个方法

// actual method
public Object call() throws Exception {
return call(); // the other call
}

// your implementation
public String call() throws Exception {
Thread.dumpStack();
return "Hello "+who+" from callable";
}

(请注意,这在源代码中是不可能的,因为这两种方法具有相同的签名。)

这在其他问题和答案中有进一步解释:

关于java - 使用 Callable 时出现奇怪的调用堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28551014/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com