2014-09-11 3 views
-1

스레드를 더 잘 이해하려고 노력하므로 간단한 작업을 구현하고 있습니다.스레드 깨우기 및 깨우기 스레드

나는 runnable을 구현하는 2 개의 클래스가 있습니다. 각각은 1에서 10까지의 2 개의 임의의 정수를 생성합니다. ClassA는 합계를 계산하고 ClassB는 곱셈을 계산합니다. 두 사람 모두 15 초 동안이 작업을 반복하고 있습니다.

두 개의 정적 및 동기화 된 메서드 setVal 및 getVal이있는 General이라는 다른 클래스가 있습니다. 각 스레드는 각 계산/반복 후에 General.setVal (result)를 호출합니다. setVal은 이전 값보다 숫자에 더 가깝기 만 값을 설정합니다. getValue는 값만 가져옵니다.

각 스레드를 시작하는 메인 클래스가 있습니다. 그런 다음 스레드에 의해 설정된 값을 출력하는 20 초 동안 루프가 있습니다. 그래서 getValue를 호출하고 그것을 인쇄합니다.

하나의 반복 작업 후에 각 스레드가 기다리고 다른 하나에게 반복 작업을 알려주는 등 ... 어떻게 처리 할 수 ​​있습니까?

public class Particle1 implements Runnable{ 

    //private int x; 
    private static final int max = 10; 
    private static final int min = 1; 

    public void run(){ 
     long t= System.currentTimeMillis(); 
     long end = t+15000; 
     while(System.currentTimeMillis() < end) { 
      Random rand = new Random(); 
      int a = rand.nextInt((max - min) + 1) + min; 
      int b = rand.nextInt((max - min) + 1) + min; 

      int x = a+b; 
      System.out.println("P1: "+a+"+"+b+"="+x); 
      Gather.setRes(x); 
      //i want it here to sleep until the other one wakes it up. 
     } 
    } 

} 


public class Particle2 implements Runnable{ 

    //private int x; 
    private static final int max = 10; 
    private static final int min = 1; 

    public void run(){ 
     long t= System.currentTimeMillis(); 
     long end = t+15000; 
     while(System.currentTimeMillis() < end) { 
      Random rand = new Random(); 
      int a = rand.nextInt((max - min) + 1) + min; 
      int b = rand.nextInt((max - min) + 1) + min; 

      int x = a+b;    
      System.out.println("P2: "+a+"+"+b+"="+x); 
      Gather.setRes(x); 
      //i want it here to sleep until the other one wakes it up. 
     } 
    } 

} 


public class Main { 

    public static void main(String[] args) throws InterruptedException { 

     Thread thread1 = new Thread(new Particle1()); 
     Thread thread2 = new Thread(new Particle2()); 
     thread1.start(); 
     thread2.start(); 


     long t= System.currentTimeMillis(); 
     long end = t+20000; 
     while(System.currentTimeMillis() < end) { 
      System.out.println("Minimum is: "+Gather.getRes()); 
      Thread.sleep(1000); 
     } 
     return; 
    } 

} 


public class Gather { 

    public Gather() { 
     // TODO Auto-generated constructor stub 
    } 

    private static int res=1000000; 

    public static int getRes() { 
     return res; 
    } 

    public synchronized static void setRes(int inres) { 
     if(Math.abs(inres-250)<res){ 
      res = inres; 
     } 
    } 



} 
+0

두 스레드가 적대적으로 작동하는 것을 의미합니까? (일종의) 멀티 스레딩의 목적을 이기기 때문에! – jbutler483

+1

많은 초보자가 두 개 이상의 스레드를 번갈아 가며 만드는 방법을 묻습니다. 그렇게 할 동기 객체를 만들 수 있지만 그와 같은 객체는 찾을 수 없습니다 왜냐하면 프로그램은 두 개 이상의 스레드가 동시에 작동 할 수 없기 때문에 하나의 스레드가 모든 스레드를 수행하도록함으로써 프로그램을 더 간단하게 만들 수 있습니다. 스레드의 전체 요점은 두 개 이상의 스레드가 동시에 다른 일을 할 수 있다는 것입니다. –

답변

1

사용하여 스레드가되지 서로 잠금 단계에서, 일반적으로 모든 스레드가 독립적으로 실행할 때의 운동입니다 :

여기 내 코드입니다.

그러나 스레드가 그들 사이에서 통신해야하는 경우가 있습니다.이 경우에는 BlockingQueue의 형식을 사용하여 스레드간에 통신하는 것이 일반적입니다.

public class TwoThreads { 
    public static void main(String args[]) throws InterruptedException { 
    System.out.println("TwoThreads:Test"); 
    new TwoThreads().test(); 
    } 

    // The end of the list. 
    private static final Integer End = -1; 

    static class Producer implements Runnable { 
    final Queue<Integer> queue; 

    public Producer(Queue<Integer> queue) { 
     this.queue = queue; 
    } 

    @Override 
    public void run() { 
     try { 
     for (int i = 0; i < 1000; i++) { 
      queue.add(i); 
      Thread.sleep(1); 
     } 
     // Finish the queue. 
     queue.add(End); 
     } catch (InterruptedException ex) { 
     // Just exit. 
     } 
    } 

    } 

    static class Consumer implements Runnable { 
    final Queue<Integer> queue; 

    public Consumer(Queue<Integer> queue) { 
     this.queue = queue; 
    } 

    @Override 
    public void run() { 
     boolean ended = false; 
     while (!ended) { 
     Integer i = queue.poll(); 
     if (i != null) { 
      ended = i == End; 
      System.out.println(i); 
     } 
     } 
    } 

    } 

    public void test() throws InterruptedException { 
    Queue<Integer> queue = new LinkedBlockingQueue<>(); 
    Thread pt = new Thread(new Producer(queue)); 
    Thread ct = new Thread(new Consumer(queue)); 
    // Start it all going. 
    pt.start(); 
    ct.start(); 
    // Wait for it to finish. 
    pt.join(); 
    ct.join(); 
    } 

} 

이 진정으로 당신이 동일한 메커니즘을 사용할 수있는 두 개의 스레드간에 동기화하지만 대신 SynchronousQueue을 사용하려면 예를 들면 다음과 같습니다.

관련 문제