2017-12-25 13 views
1

목표 : 생산자 스레드와 소비자 스레드가 상호 작동 할 수 있도록 두 개의 스레드를 만들려면 첫 번째 스레드가 두 번째 스레드보다 생산자 역할을하며 그 반대의 경우도 마찬가지입니다.Java 다중 스레드 프로그램에서 생산자 소비자 스레드의 상호 교환 가능한 역할

세부 사항 : 그들은 버퍼를 통해 서로 통신하며 하나의 정수 크기를 저장합니다. 예를 들어 첫 번째 스레드가 1을 생성하면 두 번째 스레드는이를 소비하고 2를 생성 한 다음 첫 번째 스레드는 2를 소비하고 다음 세 개의 정수를 생성하고 Consumer는 하나씩 소비합니다. 그 후에 두 스레드가 종료됩니다. 또한 두 스레드가 모두 통신을 시작할 수 있어야합니다.

다음 코드를 작성하려고했습니다.

import java.util.Random; 
class CommonItem { 
boolean flag = false; 
int arr[]; 

public synchronized void Send(String msg) { 
    if (flag) { 
     try { 
      wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
    System.out.println(msg); 
    flag = true; 
    notify(); 
} 

public synchronized void Receive(String msg) { 
    if (!flag) { 
     try { 
      wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    System.out.println(msg); 
    arr = send_random(); 
    for (int item: arr) { 
     System.out.println(item); 
    } 

    flag = false; 
    notify(); 
} 

synchronized int[] send_random(){ 
    int[] arr = new int[3]; 
    Random random= new Random(); 
    for (int i = 0; i < 3; i++) { 
     arr[i]=random.nextInt(100); 
    } 
    return arr; 
} 
} 
class T1 implements Runnable { 
CommonItem Ci; 

public T1(CommonItem Ci) { 
    this.Ci = Ci; 
    new Thread(this, "producer").start(); 
} 

public void run() { 
    while (true) 
    Ci.Send("sent :1"); 
} 
} 

class T2 implements Runnable { 
CommonItem Ci; 

public T2(CommonItem m2) { 
    this.Ci = m2; 
    new Thread(this, "Consumer").start(); 
} 

public void run() { 
    while (true) 
    Ci.Receive("received :2"); 
} 
} 
public class TestClass { 

public static void main(String[] args) { 

    CommonItem m = new CommonItem(); 
    new T1(m); 
    new T2(m); 
} 
} 

예상 출력은

sent :1 

received :1 

sent :2 

received :2 

sent :57 4 13 

received :57 4 13 

이다 그러나 나는 다음과 같은 출력을 OUTPUT

sent :1 

received :2 

57 

4 

13 

제안하십시오를받을 경우 코드에 어떤 수정이나하는 방법에 대한 아이디어 주어진 문제를 다른 방법으로 풀어 라. 미리 감사드립니다. 둘째 의해 처음 25 6 57
수신 소자

+0

어떻게 대기 잘못 사용합니다. 오라클 튜토리얼을 참조하십시오, 나는 그것에 대해 여러 가지 답변을했습니다. 또한 일반적인 데이터 구조에 넣는 것과는 대조적으로 잠금 코드를 작업에 넣는 것은 나쁜 생각처럼 보입니다. 당신은 단순해야하고 복잡해질 뭔가를 가져갔습니다. 또한 코드 규칙을 무시하면 좋지 않습니다. –

답변

1
public class CommonItem { 
    boolean receiver = false; 
    List<Integer> list = new ArrayList<>(); 

    public void receive() throws InterruptedException { 
     String name = Thread.currentThread().getName(); 
     synchronized (list) { 
      while (list.isEmpty()) { 
       list.notify(); 
       list.wait(); 
      } 

      // Receive all elements 
      System.out.printf("Receiving elements by %s:\t", name); 
      for (int val : list) { 
       System.out.print(val + " "); 
      } 
      list.clear(); 
      System.out.println(); 
      list.notify(); 
      list.wait(); 
     } 
    } 

    public void send() throws InterruptedException { 
     String name = Thread.currentThread().getName(); 
     synchronized (list) { 
      while (!list.isEmpty()) { 
       list.notify(); 
       list.wait(); 
      } 
      // Sending elements 
      int[] arr = get_random(); 
      System.out.printf("Sending elements by %s\t", name); 
      for (int ele : arr) { 
       list.add(ele); 
       System.out.print(ele + " "); 
      } 
      System.out.println(); 
      list.notify(); 
      list.wait(); 
     } 
    } 

    public int[] get_random() throws InterruptedException { 
     int[] arr = new int[3]; 
     Random random = new Random(); 
     for (int i = 0; i < 3; i++) { 
      arr[i] = random.nextInt(100); 
     } 
     Thread.sleep(1000); 
     return arr; 
    } 
} 

public class ThreadTask implements Runnable { 

    private CommonItem item; 
    private boolean receiver; 

    public ThreadTask(CommonItem item, boolean receiver) { 
     this.item = item; 
     this.receiver = receiver; 
    } 

    public static void main(String[] args) { 
     CommonItem item = new CommonItem(); 
     Thread t1 = new Thread(new ThreadTask(item, false), "First"); 
     Thread t2 = new Thread(new ThreadTask(item, true), "Second"); 
     t1.start(); 
     t2.start(); 
    } 

    @Override 
    public void run() { 
     while (true) { 
      try { 
       if (receiver) { 
        item.receive(); 
       } else { 
        item.send(); 
       } 
       receiver = !receiver; 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

} 

전송 소자 : 처음에 의한 제 35 99 10
수신 소자 (25 개) 6 (57)
전송 소자 35 99 10
전송 소자 처음으로 84 11 1
두 번째 수신 요소 : 84 11 1
초당 송신 요소 68 91 53
수신 요소 첫째 : 68 91 53

+0

고맙습니다. 나는 해결책을 얻었다. –

+0

투표 할 자격이 ... – sanit

+0

코드에서 전체 솔루션을 얻었습니다. @sanit –

0
package java11; 
import java.util.*; 
import java.util.Random; 
class CommonItem 
{ 
    boolean receiver = false; 
    List<Integer> list = new ArrayList<>(); 
    int k=1; 
    public void receive() throws InterruptedException 
    { 
     String name = Thread.currentThread().getName(); 
     synchronized (list) 
     { 
      while (list.isEmpty()) 
      { 
       list.notify(); 
       list.wait(); 
      } 
      // Receive all elements 
      System.out.printf("Receiving elements by %s:\t", name); 
      for (int val : list) 
      { 
       System.out.print(val + " "); 
      } 
      list.clear(); 
      System.out.println(); 
      list.notify(); 
      list.wait(); 
     } 
    } 

    public void send(int i) throws InterruptedException 
    { 
     String name = Thread.currentThread().getName(); 
     synchronized (list) 
     { 
      while (!list.isEmpty()) 
      { 
       list.notify(); 
       list.wait(); 
      } 
      // Sending elements 
      int[] arr; 
      if(i<3) 
      { 
       arr = get_random(k); 
       k++; 
      } 
      else 
      { 
       arr = get_random1(); 
      } 
      System.out.printf("Sending elements by %s\t", name); 
      for (int ele : arr) 
      { 
       list.add(ele); 
       System.out.print(ele + " "); 
      } 
      System.out.println(); 
      list.notify(); 
      list.wait(); 
     } 
    } 

    public int[] get_random(int k) throws InterruptedException 
    { 
     int[] arr = new int[1]; 
     arr[0] = k; 
     Thread.sleep(1000); 
     return arr; 
    } 

    public int[] get_random1() throws InterruptedException 
    { 
     int[] arr = new int[3]; 
     Random random = new Random(); 
     for (int i = 0; i < 3; i++) 
     { 
      arr[i] = random.nextInt(100); 
     } 
     Thread.sleep(1000); 
     return arr; 
    } 
} 

public class Java11 implements Runnable 
{ 
    private CommonItem item; 
    private boolean receiver; 

    public Java11(CommonItem item, boolean receiver) 
    { 
     this.item = item; 
     this.receiver = receiver; 
    } 

    public static void main(String[] args) 
    { 
     int choice; 
     CommonItem item = new CommonItem(); 
     System.out.println("Who should start first?:Thread 1 or Thread 2"); 
     Scanner sc=new Scanner(System.in); 
     choice=sc.nextInt(); 
     if(choice==1) 
     { 
      Thread t1 = new Thread(new Java11(item, false), "First"); 
      Thread t2 = new Thread(new Java11(item, true), "Second"); 
      t1.start(); 
      t2.start(); 
     } 
     else if(choice==2) 
     { 
      Thread t1 = new Thread(new Java11(item, true), "First"); 
      Thread t2 = new Thread(new Java11(item, false), "Second"); 
      t1.start(); 
      t2.start(); 
     } 
    } 

    @Override 
    public void run() 
    { 
     int i=1; 
     while (i<=3) 
     { 
      try 
      { 
       if (receiver) 
       { 
        item.receive(); 
       } 
       else 
       { 
        item.send(i); 
       } 
       receiver = !receiver; 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      i++; 
     } 
    } 
} 

약간의 변화는 문제 설명이 요구하는대로 정확한 출력을 얻을 수 SANIT의 코드에서 만들어집니다.

출력 :

Who should start first?:Thread 1 or Thread 2 
1 
Sending elements by First 1 
Receiving elements by Second: 1 
Sending elements by Second 2 
Receiving elements by First: 2 
Sending elements by First 90 95 28 
Receiving elements by Second: 90 95 28 

Who should start first?:Thread 1 or Thread 2 
2 
Sending elements by Second 1 
Receiving elements by First: 1 
Sending elements by First 2 
Receiving elements by Second: 2 
Sending elements by Second 42 10 33 
Receiving elements by First: 42 10 33 

는 @Sanit 감사드립니다.

Solved- @Kunjan라나

+0

두 개의 스레드 사이의 통신은 1을 보내면 시작됩니다. –