2017-11-03 2 views
1

"Java에서 스레드 죽이는 방법"항목을 많이 읽고 스레드를 계속 실행해야하는지 여부를 나타 내기 위해 부울 가변 변수를 사용하는 방법을 발견했지만이 변수를 사용하는 방법을 설명한 대답을 아직 보지 못했습니다. 제대로 지금 내 이해를 바탕으로 두 클래스 (기본 및 실행 가능한)스레드를 죽이는 용도로 volatile을 올바르게 사용하는 방법은 무엇입니까?

에 나는 그런 식으로 할 것 :

public class Server { 

    private volatile boolean isRunning = true; 

    public Server(...) { } 

    public static void main(...) 
     ... 
     new Thread(new Process(isRunning)).start(); 
     ... 
    } 

    public void shutdown() { 
     isRunning = false; 
    } 

} 

public class Process implements Runnable { 

    private volatile boolean isServerRunning; 

    public Process(boolean isServerRunning) { 
     this.isServerRunning = isServerRunning; 
    } 

    @Override 
    public void run() { 
     ... 
     while(isServerRunning) {...} 
     ... 
    } 

} 

내 질문 : 나는에 isRunning 변수를 제공해야 스레드의 Runnable를로 내가하는 것처럼 논쟁? 또한 Runnable 클래스 안에서이 변수를 휘발성 변수로 정의해야합니까? 코드를 개선하기 위해 수정할 사항이 있습니까?

답변

4

코드에서 isRunning 값을 복사합니다. See a question about this.

Server을 실행 가능으로 제공하거나 처리해야합니다. 그렇지 않으면 서버의 isRunning 필드를 참조하십시오.

public class Server ... { 
    private volatile boolean isRunning = true; 
    public boolean isRunning() { return this.isRunning; } 
    ... 
} 

public class Process implements Runnable { 

    private final Server server; 

    public Process(Server server) { 
     this.server = server; 
    } 

    @Override 
    public void run() { 
     ... 
     while(server.isRunning()) {...} 
     ... 
    } 

} 

Explaination은 : 실행 가능한의 스레드는 항상 새로운 가치를 얻을 수 있도록 volatile 변수에 액세스 무엇 isRunning 호출합니다.

대체 : 서버의 필드에 쓰기/읽기를 보호하여 synchronized을 사용하십시오. PoV의 결과는 같습니다.

대체 2 : 서버에 AtomicBoolean을 사용하면 전체 서버 대신 참조를 전달할 수 있습니다. 그래도 그럴 수는 없지만, (서버의) 내부 IMHO를 드러내는 것과 같은 느낌이 듭니다.

+0

전체 '서버'를 Runnable에 제공하는 것이 좋은 습관입니까? 자원 낭비가 조금 낭비되지 않습니까? (내가 수백 또는 수천 개의 '프로세스'가 실행되고 있다고 가정 해 봅니다.)'프로세스 '내부에서 다른 스레드를 시작한다면, 그 스레드에 대해해야 할 일과 똑같은 일을해야합니까? 새 스레드 (새 프로세스 (this)). start();'? – tom

+0

@tom 예, 서버에 대한 참조를 항상 생성 한 모든 실행 파일에 전달해야합니다. 리소스 낭비와 관련해서는 이것이 미세 최적화이며 필요시에만 수행해야합니다. –

관련 문제