2014-11-15 2 views
0

주어진 클래스에서 CompletableFuture 속성을 실행하려고합니다. 만약 내가 그렇게 초기화했다면 위험 할 수 있으며 아마도 부분적으로 생성 된 객체를 생성 할까?부분적으로 구성된 객체에 대한 참조 이스케이프입니까?

public class MyClass { 

    public final CompletableFuture<BigDecimal> myExpensiveVal = CompletableFuture.supplyASync(() -> calculateExpensiveMethod(this)); 

//... 
} 
+0

예, 필드 이니셜 라이저입니다. – tmn

+0

기술적으로 올바른 수정을했습니다. 나는 이클립스에서 이것을 작성해야한다. – tmn

답변

1

CompletableFuture.supplyASync이 공급자 공사중 인스턴스에 대한 참조가있는 경우는 다른 쓰레드 볼 불완전한 오브젝트 인스턴스하게 this 누설은 물론의 제공된 다른 스레드 Supplier하고, 를 보낸다 심지어 공백도 final 게재 보증.

이 특별한 경우에 당신이 재현성 탈출이 자리 할 수 ​​있도록 분명하다 :

여기
public class EscapingThis { 

    public final CompletableFuture<BigDecimal> myExpensiveVal 
       = CompletableFuture.supplyAsync(() -> calculateExpensiveMethod(this)); 
    final int fourtyTwo; 

    public EscapingThis() { 
     System.out.println(Thread.currentThread()+" starts creating "+this); 
     try { 
      myExpensiveVal.get(); 
     } catch (InterruptedException|ExecutionException ex) { 
      Logger.getLogger("EscapingThis").log(Level.SEVERE, null, ex); 
     } 
     System.out.println("still incomplete"); 
     fourtyTwo=42; 
     System.out.println("leaving constructor"); 
    } 

    static BigDecimal calculateExpensiveMethod(EscapingThis instance) { 
     System.out.println(Thread.currentThread() 
           +" says: hello incomplete instance "+instance); 
     System.out.println("fourtyTwo = "+instance.fourtyTwo); 
     return BigDecimal.ONE; 
    } 
    public static void main(String... arg) { 
     new EscapingThis(); 
    } 
} 

당신이 still incomplete 있는지에 대한 leaving constructor전에 hello incomplete instance [email protected]fourtyTwo = 0을 볼 수 있습니다. 그러나 타이밍이 정의되지 않았으므로 hello incomplete … 메시지 뒤에 Thread[main,5,main] starts creating … 메시지가 표시 될 수도 있습니다.

calculateExpensiveMethod이 인스턴스 메서드 인 경우 인스턴스 누설을 위해 this 매개 변수가 필요하지 않습니다. 인스턴스 메서드가 호출 될 this에 대한 묵시적인 참조는 누수되는 참조이기도합니다.

관련 문제