2017-12-25 5 views
1

Ziel: Erstellen von zwei Threads, sodass Producer- und Consumer-Threads austauschbar funktionieren, d. H. Wenn der erste Thread als Producer fungiert und der zweite als Consumer und umgekehrt.Austauschbare Rolle von Producer-Consumer-Threads in Java Multithreaded Programm

Details: Sie kommunizieren miteinander über einen Puffer, Speichern einer Ganzzahlgröße. Wenn zum Beispiel der erste Thread 1 erzeugt, dann verbraucht der zweite Thread ihn und erzeugt 2 und dann verbraucht der erste Thread 2 und erzeugt die nächsten drei ganzen Zahlen und der Verbraucher verbraucht sie nacheinander. Beide Threads beenden danach. Auch beide Threads sollten in der Lage sein, die Kommunikation zu initiieren.

Ich habe versucht, den folgenden Code zu schreiben.

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); 
} 
} 

Die erwartete Ausgabe ist

sent :1 

received :1 

sent :2 

received :2 

sent :57 4 13 

received :57 4 13 

aber ich bekomme die folgende Ausgabe OUTPUT

sent :1 

received :2 

57 

4 

13 

Bitte vorschlagen, wenn eine Korrektur im Code oder eine Idee, wie man Lösen Sie das gegebene Problem auf eine andere Weise. Vielen Dank im Voraus.

+0

Wie Sie verwenden Warte falsch ist. Siehe das Orakel-Tutorial, außerdem habe ich mehrere SO-Antworten dazu. Es ist auch keine gute Idee, den Sperrcode in die Aufgaben zu setzen, anstatt ihn in die gemeinsame Datenstruktur zu setzen. Du hast etwas genommen, das einfach und komplex sein sollte. Auch das Nichtbeachten von Code-Konventionen ist nicht gut. –

Antwort

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(); 
      } 
     } 
    } 

} 

Senden Elemente von First 25 6 57
Empfangselemente durch Second: 25 6 57
Senden Elemente durch Second 35 99 10
Empfangselemente von First: 35 99 10
Senden Elemente nach Erste 84 11 1
Empfangselemente nach Sekunde: 84 11 1
Sendeelemente nach Sekunde 68 91 53
Empfangselemente nach Erstens: 68 91 53

+0

Danke. Ich habe die Lösung. –

+0

Verdiene ich eine Stimme ... :-) – sanit

+0

Ich habe die ganze Lösung von Ihrem Code @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++; 
     } 
    } 
} 

Geringfügige Änderungen sind in Sanit Code gemacht genaue Ausgabe zu erhalten, wie durch die Problemstellung gefordert.

OUTPUT:

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 

Danke @Sanit.

Solved- @Kunjan Rana

+0

Beachten Sie hier, dass die Kommunikation zwischen den beiden Threads beginnt, indem Sie 1 senden. –

Verwandte Themen