2012-03-08 4 views
0

여러 스레드에서 반복자를 공유하는 것과 관련하여 몇 가지 사항을 테스트하려고했습니다. 나는 다른 스레드에 동일한 맵을 통해 반복하도록되어있는 매우 단순한 (매우 바보 같은) 프로그램을 작성했습니다. 여기 코드는 다음과 같습니다멀티 스레딩이 예상대로 작동하지 않습니다.

final Map<Integer, Integer> m = new HashMap<Integer, Integer>(); 
    final Random r = new Random(); 
    for(int i = 0; i< 1000 ; i++){ 
     m.put(r.nextInt(10000), r.nextInt(10000)); 
    } 
    Thread t1 = new Thread(new Runnable(){ 

     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      Iterator<Integer> it = m.keySet().iterator(); 
      it.next(); 
      for(Integer i : m.keySet()){ 
       System.out.println("T1 " + i); 
       try { 
        Thread.sleep(r.nextInt(100)); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 

    }); 

    Thread t2 = new Thread(new Runnable(){ 

     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      Iterator<Integer> it = m.keySet().iterator(); 
      it.next(); 
      for(Integer i : m.keySet()){ 
       System.out.println("T2 " + i); 
       try { 
        Thread.sleep(r.nextInt(100)); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 

    }); 

    t1.run(); 
    t2.run(); 

을 지금, 나는 동시 어떤 종류의 수정, 또는 "T1"콘솔에서 "T2"메시지 모두의 혼합물의 예외를 얻을 중 하나를 기다리고 있었다이 프로그램을 실행할 때. 무슨 일이 생기면 내 프로그램은 스레드 1의 맵에서 모든 값을 출력하고 THEN은 스레드 2로 진행합니다. 왜이 직렬화 가능한 동작이 여기의 경우입니까?

답변

6

run 대신 t1.start()t2.start()으로 전화해야합니다.

run을 호출하면 run 메서드의 코드가 실행됩니다.
start은 새로운 스레드를 시작합니다.

+0

와우 ... 그런 어리석은 질문에 정말 미안합니다. 매우 즉각적인 답장을 보내 주셔서 감사합니다. – Bober02

+3

문제 없습니다. 나는 과거에 똑같은 실수를 여러 번했기 때문에 너무 빨리 알아 차렸다. 스레드 용 API는이 점에서 약간 저조한 것으로 생각합니다.이 실수를하기는 너무 쉽습니다. – Tim

+0

@Tim 전적으로 그것에 동의합니다. 그리고 Bober02, 나는 꽤 많은 사람들이 실수를 저질렀다고 생각합니다. 그래서 땀을 흘리지 마십시오. 그것은 "스레드"의 "they/they/they/they"입니다. :) – yshavit

2

t.start() 대신 t.run()을 실행 중이므로 단일 스레드 (주 스레드)에서 작업을 수행하고 있습니다.

두 개의 스레드를 사용한다고해서 인터리브 된 실행이 항상 발생하는 것은 아닙니다. 종종 순차적으로 작업을 수행하는 것이 더 효율적이므로 JVM은 실제 작업을 순차적으로 스케줄링합니다.

표준 해시 맵의 동시 수정 감지는 최선의 노력이며 보증 된 메커니즘이 아닙니다.

관련 문제