Java多线程程序中生产者消费者线程的可互换角色

时间:2017-12-25 05:31:28

标签: java multithreading producer-consumer

目标:创建两个线程,使生产者和消费者线程可以互换,即如果第一个线程充当生产者而不是第二个充当消费者,反之亦然。

详细信息:它们通过缓冲区相互通信,存储一个整数大小。例如,如果第一个线程产生1,则第二个线程消耗它并产生2,然后第一个线程消耗2并产生接下来的三个整数,消费者逐个消耗它们。 两个线程都在此之后终止。 两个线程都应该能够启动通信。

我尝试编写以下代码。

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

但我得到以下输出 的输出

sent :1

received :2

57

4

13

请建议代码中是否有任何更正或任何有关如何以其他方式解决给定问题的想法。提前谢谢。

2 个答案:

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

}
  

通过First 25 6 57发送元素   第二次接收要素:25 6 57
  第二次发送元素99 99 10   通过First接收元素:35 99 10
  首先发送元素84 11 1   第二次接收要素:84 11 1   通过Second发送元素68 91 53
  第一部分接收要素:68 91 53

答案 1 :(得分:0)

"Volumes": {
    "/var/lib/mysql": {}
},

在Sanit的代码中进行了轻微的更改,以获得问题陈述所要求的精确输出。

<强> 输出:

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。

解决 - @Kunjan Rana