2014-10-16 2 views
3

Java를 배우고 있지만 동기화 문제가 있습니다. 나는 많은 자바 스레드에서 숫자의 인쇄 목록을 원하는 각 스레드 order.I에 갈 때 내가 많이 이해하지 않기 때문에 동기화를 사용하여 문제가 생겼어. 이해하는데 도움이 될 수 있습니까?Java 기본 동기화 스레드

1-thread1 
2-thread2 
3-thread1 
4-thread2 
5-thread1 
6-thread2 
... 
48-thread2 
49-thread1 

내 고장 코드 :

첫째
public class ManyThreadsAdd { 
    public static int index = 0; 

    public static void main(String[] args) { 
     ManyThreadsAdd myClass = new ManyThreadsAdd(); 
     Thread thread1 = new Thread(myClass.new RunnableClass()); 
     Thread thread2 = new Thread(myClass.new RunnableClass()); 

     thread1.start(); 
     thread2.start(); 
    } 

    class RunnableClass implements Runnable { 
     public synchronized void run() { 
      while (index < 49) { 
       try { 
        Thread.sleep(100); 
        System.out.println(index+"-" +Thread.currentThread()); 
        index = index + 1; 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
+1

당신은()'여기'대기()'사용'통보해야합니다. 당신은 당신의 출력을 달성하기 위해 스레드 사이에 일종의 의사 소통이 필요합니다. – TheLostMind

+0

예 기다려보십시오.하지만 항상 잘못된 예외가 발생했습니다. 대기 클래스를 사용하여 알리는 공통 클래스일까요? – JoeJoeJoeJoe4

+0

공유 잠금을 사용해야합니다. http://stackoverflow.com/q/6017281/217324에 대한 답변을 참조하십시오. 같은 문제이기 때문에이 속임수로 닫는 투표. 나는 당신을 위해 좋은 하나를 고르려고했지만,이 질문을 해결하지 않으면 "자바 멀티 스레딩 홀수 사이트 : stackoverflow.com"에 대한 답변을,이 문제에 게시 된 질문이 많이 있습니다. –

답변

2

당신이하고 싶은 일에 달려 있습니다.

인쇄 순서를 바꾸는 간단한 방법은 같은 개체를 동기화하는 것입니다.이 경우 색인 또는 다른 개체를 사용할 수 있습니다.

public class ManyThreadsAdd { 
    public static AtomicInteger index = new AtomicInteger(0); 

    public static void main(String[] args) { 
     ManyThreadsAdd myClass = new ManyThreadsAdd(); 
     Thread thread1 = new Thread(myClass.new RunnableClass()); 
     Thread thread2 = new Thread(myClass.new RunnableClass()); 

     thread1.start(); 
     thread2.start(); 
    } 

    class RunnableClass implements Runnable { 
     public void run(){ 
      synchronized(index){ 
       while(index.get() < 49){ 
        try { 
         Thread.sleep(100); 
         System.out.println(index.get()+"-" +Thread.currentThread()); 
         index.incrementAndGet(); 
         index.notify(); 
         index.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    } 
} 
+0

이것은 내가 가장 잘 이해합니다. Atomic이 증가한 것을 알기 쉽고 notify() 및 wait()를 알기 쉽습니다. 감사 – JoeJoeJoeJoe4

2

, 본질적으로 멀티 스레딩이 비동기, 당신은 지정할 수 없습니다

나는 출력을하지만 때로는 잘못된 잤다 스레드 원하는이보고 싶어 이 쓰레드가 실행되는 순서.

1-thread1 
2-thread2 
3-thread1 
4-thread2 
5-thread1 
6-thread2 
... 
48-thread2 
49-thread1 

이 두 번째로, 당신은 public synchronized void run()synchronized 키워드를 추가하여 아무것도 얻을 수 없다 : 당신은 아래와 같은 출력을 원하는 경우, 루프를 사용합니다. 즉, 언제든지 한 번에 하나의 스레드 만 해당 메서드를 호출 할 수 있습니다. 각 스레드에 대해 새로운 클래스를 생성 할 때 이것은 의미가 없습니다.

셋째, 스레드간에 동기화가 필요한 경우 작업을 추가하고 스레드가 한 번에 하나씩 읽는 큐를 사용하십시오.

+0

당신은 항상 새로운 RunnableClass를 열어서 동기화를하지 않을 것입니다. 싱글 톤 클래스로 만듭니다. –