2016-11-01 5 views
0

스레드를 생성 할 때 이해할 수 없습니다. 첫 번째 경우와 두 번째 경우에는 무엇을 얻을 수 있습니까?자바에서 스레드를 만듭니다.

일반적으로 차이점은 무엇입니까?

첫 번째 경우 당신은 하나 개의 스레드 인스턴스를 생성하고 5 개 다른 스레드 인스턴스를 생성하는 두 번째에서 5 번을 실행하려고 시도하고이를 실행하려고에서

ExecutorService executorService = Executors.newCachedThreadPool(); 

for(int i = 0;i < 5; i++){ 
    NewThread newThread = new NewThread(Thread.MAX_PRIORITY); 
    executorService.execute(newThread); 
} 
+0

'run()'메소드가 무엇을하는지에 따라 다릅니다. 참고 : 두 경우 모두'NewThread'를 시작하지 않으므로 실제로 실행되지 않습니다. Thread 객체를 만드는 것은 시작과 동일하지 않습니다. –

+2

당신이 얻을 것은 전적으로 NewThread의 코드에 달려 있습니다. –

답변

0

ExecutorService executorService = Executors.newCachedThreadPool(); 

NewThread newThread = new NewThread(Thread.MAX_PRIORITY); 
for(int i = 0;i < 5; i++){ 
    executorService.execute(newThread); 
} 
. 그 질문에 대답합니까?

+0

오, 네, 정말 고마워요! –

0

귀하의 질문은 잘못된 이름입니다. 당신은

executorService.execute(newThread); 

을 수행하고 (스레드 풀을 기반으로) 해당 서비스가 스레드 다루는 이유 방법 아마 당신은 지금 생각해보고있다.

간단한 답변 : 그렇지 않습니다. 해당 인터페이스 Executor.execute()Runnable 개체를 사용합니다. 즉

: 당신의 코드는 실행 방법 당신의 클래스 NewThread가 제공하는 호출합니다.

질문에 대한 "직접적인"대답은 다음과 같습니다. 첫 번째 경우 과 동일한 실행 파일을 실행 프로그램에 5 회 전송합니다. 두 번째 경우에는 실행자에게 5 실행 파일을 보냅니다.

서로 다른 의미의 개체 - 동일한 클래스이므로 동일한 예제가 두 예제에서 모두 발생해야합니다. 너는 더러운 것을하지 않으면 정적 인 NewThread에서; 귀하의 질문에 대한 전반적인 인상을 감안할 때 너무 놀랄 일은 아닙니다.

+0

네 말이 맞아, 내 질문에 잘못 이름이 붙어있는 걸 알았어. 고마워. –

0

나는 그것을 시도하지는 않았지만 첫 번째 경우는 한 번 실행 한 다음 예외를 던지기 시작해야합니다. Thread의 인스턴스가 종료되면 다시 시작하려고하면 불법입니다. See the javadoc for start :

IllegalThreadStateException - 스레드가 이미 시작된 경우.

두 번째 예제는 5 개의 개별 스레드 인스턴스를 생성하기 때문에 두 개의 예제가 더 유용합니다.

+0

답장을 보내 주셔서 감사합니다. 그러나 첫 번째 경우와 두 번째 모든 것이 성공적으로 실행되면. 질문이 있습니다. –

1

당신이 제공 한 것이 최선의 답입니다. 첫 번째 경우에는 아마 오류가 발생할 것입니다. 두 번째 방법은 완전히 안전합니다 (물론 안전하지 않은 일을하지 않는다고 가정 할 때).

내가 아는 한별로 도움이되지 않으므로 배경을 알려 드리겠습니다.

class NewThread implements Runnable { 
    void run(){ 
      //do something 
    } 
} 

지금, 우리는 실제 구현 무엇 모르겠지만, 우리는 여전히 몇 가지 분석을 할 수 있습니다 : 그것은이 같은 방법 무효 실행()를해야하므로

NewThread는 대부분의 아마, Runnable를 구현합니다. 예제의 전체 결과는 NewThread가 상태 저장인지 또는 상태 저장인지에 따라 다릅니다. "Stateful"은 해당 클래스의 인스턴스에 상태 (예 : 일부 내부 필드 (특성))가 있음을 의미합니다. "무국적자"는 단지 "상태가 없다".

NewThread가 상태 비 저장 인 경우 결과는 동일하게됩니다. ExecutorService 아래에서 새 스레드에서 run() 메소드를 실행하며 어쨌든 변수 상태가 없으므로 아무런 문제가 없습니다.

NewThread가 상태 저장 인 경우 첫 번째 예제에 몇 가지 문제가있을 수 있습니다. 컴파일러는 코드가 정상이지만 여기서는별로 도움이되지 않지만 논리가 깨질 수 있습니다. 상상해보십시오 :

class NewThread implements Runnable { 
    int x = 0; 
    void run(){ 
      while (x<10) 
       x = x + 1; 
    } 
} 

여기에 표시되는 내용은 경쟁 조건 핸드북의 예입니다. 나보다 나은 저자는 저보다 더 나은 방법으로 문제를 설명했습니다. 따라서 this, thisthis과 같은 링크를 제공 할 것입니다. 물론 Google을 사용하십시오. 기본적으로,이 경우의 경쟁 조건은 x = x + 1 일 때 먼저 x를 읽고 나서 쓰기를해야한다는 것입니다. 읽기와 쓰기 사이에 다른 스레드가 x의 값을 수정했을 수 있으며이 스레드가이 값을 덮어 쓰게됩니다.

NewThread가 상태 유지이지만 여전히 올바르게 작동하는 경우가 있습니다.

이 이 이
class NewThread implements Runnable { 
    AtomicInteger x = new AtomicInteger(0); 
    void run(){ 
      while (x<10) 
       x.incrementAndGet(); //getAndIncrement would work too - we don't care about the result, only about incrementing 
    } 
} 
이 이 이

는 "원자"란 그 클래스의 모든 작업이 간주됩니다 : 중 synchronized 키워드를 사용하여 (예를 들어, 위의 3 링크 참조) 또는 동기화 된 데이터 구조를 사용하여 - 당신은 당신의 코드에 의해 직접 동기화하는 경우에 발생합니다 읽기 또는 쓰기와 같은 단일 단계 (x = x + 1은 두 단계이므로 정확히 경쟁 조건으로 연결됩니다). 이미 사용 가능한 원자 클래스가 여러 개 있습니다 in JDK. 비슷한 것을 구현하고 싶다면 synchronized keyword 또는 일부 lock-like object을 사용하여 변수를 보호 할 수 있습니다.

관련 문제