2014-10-17 2 views
-1

정말 멍청한 질문입니다.하지만 저는 방법과 스레드가 아마추어 프로그래머로서 어떻게 작동하는지 이해하려고 노력하고 있습니다. 나는 이것이 나의 부분에 대한 이해의 근본적인 부족이라고 확신하지만, 좋은 사람이 나를 똑바로 놓을 수 있기를 바랍니다.다른 스레드에서 같은 메서드를 호출 할 수 있습니까?

여러 스레드를 사용하여 동일한 방법을 여러 번 호출하면 서로 독립적으로 작동하거나 서로 간섭 할 수있는 각 방법의 샌드 박스 버전을 생성합니까? 예를 들어 아래에 몇 가지 간단한 코드를 작성하여 제가 의미하는 바를 설명하려고 시도했습니다.

예에서 버튼을 클릭 할 때 호출되는 메소드가 있습니다. 두 개의 숫자를 취하여 두 번째 숫자를 합산하여 결과를 반환합니다. 이것은 곧장 보인다. 그러나 같은 방법을 사용하여 다른 계산을하고 싶지만 첫 번째 계산이 끝날 때까지 기다리지 않으려한다고 상상해보십시오. 우리는 별도의 스레드에 숫자를 추가하는 메서드를 호출하여 UI 스레드를 유지하지 않을 수 있습니다. 시원한. 좋아,하지만 우리가 이것을 두 번하면 어떨까? 아니면 세 번이나?

제가 물어 보려는 것은 "doSum"이 전달 된 숫자 아래에 처음으로 호출 될 때 10과 20입니다. 코드는 별도의 스레드에서 메서드를 실행하고 대답 30을 반환해야합니다. 두 번째 시간은 그것이 전화 번호는 30과 50이고 결과는 80이어야합니다. 어떤 이유로 인해 첫 번째 스레드의 계산이 계속 진행된다면 두 번째 동일한 메소드를 호출 할 때 덮어 쓰게됩니까? 결과 1이 80 또는 140으로 반환 될 위험이 있습니까?

누구에게나 맞는가?

public void onbuttonclicked(View v) { 

int number1; 
int number2; 
int result1, result2, result3; 


//first callculation -------------------------------------- 
number1 = 10; 
number2 = 20; 
    Thread t1 = new Thread(new Runnable() { 
     public void run() { 
     result1 = doSum(number1, number2); 
      } 
    }); 
    t1.start(); 


//second callculation ----------------------------------- 
number1 = 30; 
number2 = 50; 
    Thread t2 = new Thread(new Runnable() { 
     public void run() { 
     result2 = doSum(number1, number2); 
      } 
    }); 
    t2.start(); 

//third callculation ----------------------------------------- 
number1 = 60; 
number2 = 80; 
    Thread t3 = new Thread(new Runnable() { 
     public void run() { 
     result3 = doSum(number1, number2); 
      } 
    }); 
    t3.start(); 


} 


public static int doSum(int a, int b) 
{ 
    int result = a + b; 
    return result; 
} 
+1

변수 number1, number2 및 number3은 * final *이어야합니다. 귀하의 코드가 컴파일됩니까? – TheLostMind

+0

또는 그들을 클래스 – minghua

답변

3

알아야 할 2 가지 주요 사항이 있습니다.

  1. 2 개 스레드가 같은 방법을 호출하면

    각 스레드는 방법에 대해 다른 스택 프레임이있을 것이다. 따라서 메서드 로컬 변수는 스레드로부터 안전합니다. 한 메서드의 로컬 변수에서 변경 한 사항은 다른 스레드의 변경을 방해하지 않습니다.

  2. 두 스레드가 공유 리소스를 수정하는 경우 스레드 안정성/간섭에 대해 걱정해야합니다.

추 신 : doSum()은 처리가 거의 없습니다. 똑똑한 JVM이 실제로 인라인 인라인 일 수 있습니다.

+1

로 옮겨 주셔서 감사합니다 - 완벽한 답변과 정말 감사드립니다. – Regnodulous

+1

2에 관해서도, 하나의 스레드가 번호 (이 질문의 GUI 스레드)를 수정하고 다른 스레드가이 번호를 사용하면 걱정해야합니다. doSum()에 전달 된 숫자는 이미 경쟁 조건의 영향을받습니다. – minghua

+0

@minghua - 나는 그의 코드가 컴파일 될 것이라고 생각하지 않는다. 변수는 * final *이어야합니다. 그는 코드에 경쟁 조건이 없습니다. – TheLostMind

0

이 경우 doSum()에는 문제가 없습니다. 전달 된 매개 변수와 로컬 변수 만 사용합니다. 따라서 doSum()은 다음을가집니다.

1) 코드. 이진 명령어 코드는 자체 수정을하지 않는 한 스레드로부터 안전합니다 (절대로 그렇게하지 마십시오!).

2) 로컬 변수 및 매개 변수. 대부분의 아키텍처에서 이것은 스토리지를 등록하고 스택하는 것을 의미합니다. 각 스레드는 자체 레지스터 세트와 스택을 가지고 있기 때문에 충돌이 없어야합니다.

+0

좋습니다 - 여기서 약간의 논쟁이있는 것 같습니다. 마틴 - 가장 피드백이있는 사람으로서 나는 당신과 함께 갈 것이고, 당신은 Mr TheLostMind (첫 번째 대답)에 동의하는 것 같습니까? 몇 가지 IP를 핑 (ping)하는 기능을 호출 할 수있는 시나리오를 생각하고있었습니다. 분명히 응답 시간은 다양 할 수 있지만 변수가 로컬로 유지되는 한 서로 다른 스레드에서 동일한 메소드를 호출하여 서로 간섭하지 않고 여러 IP를 핑 (ping) 할 수 있어야합니다. – Regnodulous

+0

@ Regnodulous, t1에서 doSum()을 호출하기 전에 100ms 지연을 추가하십시오. 당신은 그것이 30, 80 또는 140인지 알 수있을 것입니다. – minghua

+0

try {Thread.sleep (100);} catch (InterruptedException e) {} – minghua

0

이러한 스레드는 독립적으로 실행되므로 결과는 임의적이며 속도는 모두 속도에 따라 다릅니다. 이것은 일반적인 경쟁 조건입니다. 어쩌면 경주 조건에 대해 읽어보아야 할 것입니다. 이해하기 어려워서는 안됩니다.

무작위로 말하자면 number1 = 30 바로 뒤에 t1이 doSum()을 호출 할 수 있으므로 result1은 50이되어야합니다.

+0

doSum()에는 경쟁이 없습니다. –

+0

doSum()에 대한 호출 지점에 도달하면 인수가 무작위로 전달됩니다. 3 개의 스레드와 메인 스레드 사이의 경쟁입니다. – minghua

0

자바의 스레드는 독립적으로 실행됩니다. 당신이 어떻게 구성하는지에 달려 있습니다. 스레드가 그림에 올 때, 결과는 항상 예측할 수 없게됩니다. 첫 번째 시도에서 얻은 결과를 의미합니다. 두 번째 시간에는 들어 가지 않습니다.

귀하의 경우, onbuttonclicked()는 메인 스레드에 의해 처리/실행되어 다른 3 스레드를 생성합니다. ThreadScheduler는 스레드가 먼저 실행됩니다. 이 작업은 초기화 프로세스가 (항상은 아니지만) 극복하는 동안 매우 빠르게 발생하기 때문입니다.

여기에서 첫 번째 스레드는 결과를 140으로 가져올 수 있습니다. 예측할 수 없습니다.

희망이 도움이됩니다.

관련 문제