2012-05-22 8 views
0

이 코드는 다른 증기 데이터에서 숫자를 읽고 전체 합계를 출력합니다. 이 코드에 문제가 있습니까? 내가 어떻게 고칠 수 있니?자바 스레드가 다른 스트림

public class Thr extends Thread{ 
static int numThr=100, sum=0; 
private int num; 
private Thr(int num){this.num =num;} 
public void run() { 
    int k = IntegerReader.get(num); 
    int count=0; 
    while(k>0) { 
     if(count%numThr==num) sum+=k; 
     count++; 
     k=IntegerReader.get(num); 
    } 
} 
public static void main(String[] a) throws Exception { 
    thr[] st =new thr[numThr]; 
    for(int i=0; i<numThr; i++) st[i] = new Thr(i); 
    for(int i=0; i<numThr; i++) st[i].start(); 
    System.out.println("sum = "+sum); 
} 
} 
+2

'this''에 문제가 우리가 여기에 대답 질문의 유형은 정말이되지이다. –

+0

왜이 코드에 문제가 있다고 생각하십니까? 예상대로 작동하지 않는 것은 무엇입니까? 'IntegerReader' 란 무엇입니까? – Jeffrey

+2

'제 차에 뭔가 이상이 있습니다. 어떻게 해결할 수 있습니까? ' –

답변

1

박쥐 바로 여러 가지가 잘못되었습니다.

  1. 합계는 여러 스레드간에 공유하고 값을 증가하는 것은 원자 작동되지 않기 때문에 당신이 일치하지 않는 값을 얻을 수 있다는 것을 의미 여러 스레드에서 증가되고있다. 여러 스레드 다중 스레드간에 공유 및 읽기 sum.getAndAdd(k)

  2. "numThr" private static AtomicInteger sum = new AtomicInteger(0);

    과이 방법을 추가

    이 가장 쉬운 수정에 합의 선언을 변경할 수있다 . numThr은 final, synchronized 또는 volatile이 아니기 때문에 다른 스레드가 그 값이 초기화되었다는 것을 보장하지 않습니다. numThr은 private static final int numThr=100

  3. 으로 지정되어야합니다. 스레드가 실행을 완료하기 전에 System.out.println("sum = "+sum);이 인쇄 될 것입니다. 합계를 인쇄하기 전에 스레드에 "조인"해야합니다 (즉, 완료 될 때까지 기다려야 함). sysout 앞에 for(int i=0; i<numThr; i++) st[i].join();을 추가하십시오.

자바 메모리 모델과 Java의 동시성에 대해 알아야한다고 생각합니다. 다음은 기본적인 튜토리얼,하지만 당신은 정말 주제에 책이 필요합니다 http://docs.oracle.com/javase/tutorial/essential/concurrency/

+0

나는 자바와 연습에서 약간의 .. 왜 '휘발성'합계를 선언하지? – mkoryak

+0

변수를 증가시키기 때문에 휘발성 일 수 없으며 sum이 증가 할 때 세 가지 연산이 발생합니다. 스레드 1은 sum (sum = 0)을 읽고 스레드 2에 의해 선점됩니다. 스레드 2는 sum (sum = 0)을 읽고 증분하여 sum (sum = 1)을 씁니다. 스레드 1은 다시 시작하여 sum (0)에 대해 읽은 값을 증가시키고 sum (sum = 1)을 씁니다. –

+0

감사합니다. Matt, 매우 도움이됩니다. –

0

예,이 코드에는 몇 가지 문제가 있습니다. 문제를 해결하는 한 가지 방법은 Java tutorial을 읽고 이해하는 것이 좋습니다. 또 다른 방법은 다른 사람에게 당신을 위해 문제를 해결하도록 요청하는 것이지만 여기서는 잘 돌아 가지 않을 것이라고 경고해야합니다.

관련 문제