2012-09-07 2 views
0

저는 Java에서 스레드에 대해 조금 배우는 중이며 어떤 것이 나를 도울 수 있는지 궁금합니다.스레드와 Java를 알아 내려고 시도했습니다.

10 개의 정수 목록을 만들었습니다. 내가 원하는 것은 여러 스레드가 들어가서 인덱스 0에서 정수를 가져 와서 인쇄하고 제거하는 것입니다. 목록에 더 이상 숫자가 없을 때까지이 작업을 수행하고 싶습니다. 지금까지 내 코드입니다.

public class SlothTest implements Runnable{ 

static ArrayList<Object> test = new ArrayList<>(); 
static int listSize; 

public static void main(String[] args) { 

    for (int i = 0; i < 10; i++){ 
     test.add(i); 
    } 

    SlothTest runner = new SlothTest(); 
    Thread alpha = new Thread(runner); 
    Thread beta = new Thread(runner); 
    alpha.setName("Alpha thread"); 
    beta.setName("Beta thread"); 
    alpha.start(); 
    beta.start(); 
} 

@Override 
public void run() { 
    listSize = test.size(); 
    while (listSize > 0){ 
     getLink(); 
    } 
} 

private synchronized void getLink(){ 
    String threadName = Thread.currentThread().getName(); 
    System.out.println(threadName + " printed " + test.indexOf(listSize - 1)); 
    test.remove(0); 
    listSize = test.size(); 
} 

} 

누군가 내가 잘못하고있는 것을 지적 할 수 있습니까?

+2

어떤 오류가 발생합니까? – Dev

답변

0

listSize > 0의 테스트가 제대로 동기화되지 않았습니다. 검사가 수행 될 때 목록은 비어 있지 않지만 스레드가 getLink()을 호출 할 때 실제로 비어있을 수 있습니다. getLink()은 void 대신에 boolean을 반환하는 것이 더 쉬울 것입니다. true은 목록이 비어 있다는 것을 나타내며 false은 각 스레드가 false을 반환 할 때까지 메소드를 계속 호출 할 수 없다는 것을 나타냅니다. 또한 항목을 제거하기 전에 목록이 getLink() 상단에 비어 있지 않은지 확인해야합니다.

@Override 
public void run() { 
    while (getLink()); 
} 

private synchronized boolean getLink(){ 
    String threadName = Thread.currentThread().getName(); 
    System.out.println(threadName + " printed " + test.indexOf(test.size() - 1)); 
    if(!test.isEmpty()){ 
     test.remove(0); 
    } 
    return !test.isEmpty() 
} 
+0

... remove (0)가 Exception을 throw 할 때까지) –

0

가서 동기화 스핀이 (거의) 단일 스레드 애플리케이션과 동일한 실행하기 때문에, 인덱스 0 소자 잡아 멀티 쓰레드 방식을 갖는 소용 없다. 여러 스레드가 읽을 수 있지만 하나만 쓸 수 있습니다.

0

기본 문제는 하나의 스레드에서 수행하는 것이 가장 효과적이라는 것입니다. JVM은 이것을 처리하지만 다른 스레드가 기회를 잡기 전에 한 스레드가 잠금을 잠그고 모든 요소를 ​​소비하도록 허용합니다.

관련 문제