为什么方法引用不会在此示例中启动线程?
package example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ESMethodReference {
int i1, i2, result = 0;
ESMethodReference(int i1, int i2){
this.i1 =i1;
this.i2 = i2;
}
public Runnable calculate(){
System.out.print("In calculate()");
return new Runnable() {
@Override
public void run() {
result += i1 + i2;
System.out.print(" creating result");
}
};
}
public static void main(String[] args) throws InterruptedException{
ESMethodReference es = new ESMethodReference(1, 1);
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 2; i++){
executorService.submit(es.calculate());
Thread.sleep(100); // Allow new thread to run
System.out.println("\tes.calculate() result incremented " + es.result );
executorService.submit(es::calculate);
Thread.sleep(100); // Allow new thread to run
System.out.println("\tes::calculate result NOT incremented " + es.result );
}
executorService.shutdown();
}
}
输出:
在calculate()中创建结果es.calculate()结果递增2
在calculate()es :: calculate结果中,NOT递增2
在calculate()中创建结果es.calculate()结果递增4
在calculate()es :: calculate结果中,NOT递增4
答案 0 :(得分:11)
因为那些是不同的东西 - 传递es::calculate
与传递相同:
new Runnable() {
@Override
public void run() {
es.calculate();
}
}
显然,这与:
不一样new Runnable() {
@Override
public void run() {
es.calculate().run();
}
}
答案 1 :(得分:5)
当您致电es.calculate()
时,会返回带有代码
Runnable
public void run() {
result += i1 + i2;
System.out.print(" creating result");
}
当您传递方法引用es::calculate
时,代码运行将是
System.out.print("In calculate()");
return new Runnable() {
@Override
public void run() {
result += i1 + i2;
System.out.print(" creating result");
}
};
执行方法的返回值和通过方法引用执行方法本身之间存在差异。
答案 2 :(得分:3)
executorService.submit(es::calculate);
相当于
executorService.submit(() -> es.calculate());
与
不一样executorService.submit(es.calculate());
前者异步创建Runnable
(不执行它),而后者异步执行相同Runnable
的(不同实例)。
作为旁注,如果只创建任务而不计算任何内容,则应该避免命名方法“ calculate ”。例如,如果将其命名为createTask()
,则会更明显地表明以下内容不会计算任何内容:
executorService.submit(es::createTask)
或者,如果您使方法实际计算结果:
public void calculate(){
System.out.print("In calculate()");
result += i1 + i2;
System.out.print(" creating result");
}
然后使用方法引用的调用将按预期工作。