2011-01-13 4 views
1

Java에서 스레드와 통신하는 매우 간단한 방법을 찾고 있습니다. 다음 예제를 고려하십시오.Java 스레드와의 간단한 통신

 

boolean pass=false; 
Thread simpleThread=new Thread(){ 
    public void run(){ 
    x=doStuff(); 
    if (x==0) pass=true; 
    } 
} 
simpleThread.start(); 
 

doStuff()가 0을 반환했는지 알아야합니다. 물론 이것은 Java에서는 합법적이지 않습니다. 그러나 올바르게 구현하려면 어떻게해야합니까? simpleThread로 작성하고 주 스레드가 읽을 수있는 일종의 Object가 필요합니다. 그 누락 된 조각은 무엇입니까?

답변

4

http://download.oracle.com/javase/6/docs/api/java/util /concurrent/atomic/package-summary.html
+0

이것은 정확히 내가 찾고있는 것입니다. 너무 간단합니다.AtomicBoolean이 날 꺼 버렸어! – User1

+0

이 예제에서'AtomicBoolean'의 사용법을 완전히 이해하지 못했습니다. 이 예제는 "비교 및 교환"의미론에 의존하지 않으며, 내 지식은 원자를 사용하는 주요 동기입니다. 전통적인 휘발성 부울을 사용하는 것은 동등해야합니다. – bluenote10

+0

@ bluenote10이 예제는 단순한 불린 홀더로서'AtomicBoolean'을 더 많이 사용하고 있습니다. 휘발성 부울은 모든 선언이 로컬 범위이고 익명 내부 클래스에서 로컬 final에만 액세스 할 수 있기 때문에 여기에서 가능하지 않습니다. –

2

두 스레드가 볼 수있는 공유 개체가 있어야합니다. 개체는 수정 가능해야합니다. 즉, Primitive 나 String, Integer, Boolean 등의 기본 객체 유형을 변경할 수 없으므로 사용할 수 없습니다.

또한 스레드 동기화를 이해하고 사용해야합니다. 당신은 Future<T>을 사용할 수 있습니다

List mylist = new ArrayList(); 

in-thread 
{ 
    synchronized(mylist) 
    { 
     mylist.add(_something_); 
    } 
} 

in-another-thread 
{ 
    synchronized(mylist) 
    { 
     mylist.get(0); // do something with result; 
    } 
} 
+0

또한 원자 클래스로보고 할 수 있습니다 : AtomicBoolean를 사용하여

ExecutorService executor = ... Future<Integer> result = executor.submit(new Callable<Integer>() { public Integer call() { return doStuff(); } }); // later. Integer x = result.get(); boolean pass = x==0; 
Jeremy

+0

의심 할 여지없이 생성 된 연산의 결과를 가져 오는 방법은 "미래"입니다 (@jon skeet 참조). – mtraut

+1

미래는 사실이지만 Future/Callable에는 마법이 없습니다./ExecutorService. 이들은 스레드 간의 위의 기본 통신을 수행하는 유틸리티입니다. 모든 훌륭한 Java 개발자는 이러한 개념을 다소 숨기는 유틸리티를 사용하는 경우에도 Java 스레딩 프리미티브를 아는 것이 도움이됩니다. –

8

:

는 여기에 목록을 사용하여 예입니다. 이와 같이 직접 새 스레드를 시작하는 대신 ExecutorService을 사용하고 Callable<T>을 전달하십시오. 그러면 Future<T>이 반환됩니다.

당신은 그때 이미 완료 여부 (원래 스레드에서) 언제든지 Future<T>을 요청하거나 은 (선택적으로 타임 아웃) 완성을 가질 때까지 단지 차단할 수 있습니다.

공유 변수를 사용하여 동등한 작업을 수동으로 수행 할 수 있지만 직접 다른 스레드에서 단일 (가능하면 복잡한) 값을 계산하는 경우에는 개인적으로 Future/Callable 접근법이 더 깨끗하다고 ​​생각합니다. 정기적으로 스레드와 통신해야하는 경우 (예 : 작업량을 늘리거나 진행 상황을 확인하려면) 적절하지 않습니다.

0

@ Jon의 제안을 설명합니다.

final AtomicBoolean pass = new AtomicBoolean(false); //making this final means we can access it in the anonymous Thread instance 
Thread simpleThread=new Thread(){ 
    public void run(){ 
    x=doStuff(); 
    if (x==0) pass.set(true); 
    } 
} 
simpleThread.start(); 
... 
pass.get(); //of course, this could return false simply because the newly spawned thread has not completed execution yet