簡體   English   中英

Java多線程程序中生產者消費者線程的可互換角色

[英]Interchangeable role of producer consumer threads in Java Multithreaded Program

目標:創建兩個線程,使生產者和消費者線程可以互換工作,即如果第一個線程充當生產者而不是第二個充當消費者,反之亦然。

詳細信息:它們通過緩沖區相互通信,存儲一個整數大小。 例如,如果第一個線程產生 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

請建議代碼中是否有任何更正或有關如何以替代方式解決給定問題的任何想法。 先感謝您。

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

}

按 First 25 6 57 發送元素
按秒接收元素:25 6 57
按秒發送元素 35 99 10
按 First 接收元素:35 99 10
通過 First 84 11 1 發送元素
按秒接收元素:84 11 1
按秒發送元素 68 91 53
按 First 接收元素:68 91 53

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。

已解決-@Kunjan Rana

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM