gpt4 book ai didi

java - 使用 Java(同步)但始终运行相同线程的生产者/消费者模型

转载 作者:行者123 更新时间:2023-11-30 08:45:39 25 4
gpt4 key购买 nike

一切看起来都很好,但是当我运行时,结果如下:

Start Thread(1): Pro2

Start Thread(2): Pro1

Start Thread(1): Con1

Start Thread(2): Con2

Pro2 Produce: EWlmJdi2KK

Left:

Pro2:EWlmJdi2KK

---Left: 1---

Con2 Consume: EWlmJdi2KK

Left:

---Left: 0---

Pro2 Produce: Nx7QPyG7vs

Left:

Pro2:Nx7QPyG7vs

---Left: 1---

Pro2 Produce: xl85Zwr80a

Left: Pro2:Nx7QPyG7vs Pro2:xl85Zwr80a

---Left: 2---

在运行时总是相同的生产者和消费者。

这是我的代码:主.java:

package com.producer;

import org.apache.commons.lang3.RandomStringUtils;

public class Main {

public static void main(String[] args) {
ThreadSynchronized semaphore = new ThreadSynchronized();
ThreadSynchronized.Producer pro = semaphore.new Producer("1");
ThreadSynchronized.Consumer con = semaphore.new Consumer("2");
new Thread(pro, "Pro2").start();
new Thread(pro, "Pro1").start();
new Thread(con, "Con1").start();
new Thread(con, "Con2").start();

}
}

线程同步.java:

package com.producer;

import java.util.LinkedList;

/**
* Created by SkyAo on 15/10/18.
*/
public class ThreadSynchronized {
private static int pid;
private static int cid;
public LinkedList<Item> items = new LinkedList<>();
private Item temp;
private int item;
private boolean flag = false;

class Producer implements Runnable {
private String name;
private int id;

public Producer(String name) {
this.name = name;
}

@Override
public void run() {
this.id = ++pid;
System.out.println("Start Thread(" + this.id + "): " + Thread.currentThread().getName());
while (true)
this.produce();
}

private synchronized void produce() {
try {

Thread.sleep((int)(Math.random()*5000)+3000);
if (items.size() < 5) {
items.add(new Item(this.id, Thread.currentThread().getName()));
temp = items.getLast();
System.out.println(temp.sourceName + " Produce: " + temp.semi);

System.out.println("Left: ");

for (Item item : items) {
System.out.println(item.sourceName + ":" + item.semi);
}

System.out.println("---Left: " + items.size() + "---");
} else {
super.wait();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
super.notifyAll();
}

}


}

class Consumer implements Runnable {
private String name;
private int id;

public Consumer(String name) {
this.name = name;
//this.id = ++cid;
}

@Override
public void run() {
this.id = ++cid;
System.out.println("Start Thread(" + this.id + "): " + Thread.currentThread().getName());
while (true)
this.consume();

}

private synchronized void consume() {
try {
Thread.sleep((int) (Math.random() * 5000) + 3000);
if (items.size() > 0) {
temp = items.removeFirst();
System.out.println(Thread.currentThread().getName() + " Consume: " + temp.semi);
System.out.println("Left: ");

for (Item item : items) {
System.out.println(item.sourceName + ":" + item.semi);
}

System.out.println("---Left: " + items.size() + "---");
} else {
super.wait();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
super.notifyAll();
}
}
}
}

我不知道发生了什么以及如何解决它,感谢您的帮助。

最佳答案

您以不同寻常的方式构建了您的解决方案。通常,生产者和消费者本身并不同步,但对他们共享的资源的访问是同步的。

考虑这个例子。在这里,MyQueue 的一个实例是共享资源——它是具有同步方法的东西。生产者和消费者本身是不同步的。

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

class MyQueue {
private int capacity;
private List<Integer> queue = new LinkedList<>();

public MyQueue(int capacity) {
this.capacity = capacity;
}

public synchronized void enqueue(int item) throws InterruptedException {
while (queue.size() == this.capacity) {
wait();
}

System.out.println("Thread " + Thread.currentThread().getName() +
" producing " + item);
queue.add(item);

if (queue.size() == 1) {
notifyAll();
}
}

public synchronized int dequeue() throws InterruptedException {
int item;

while (queue.size() == 0) {
wait();
}

item = queue.remove(0);

System.out.println("Thread " + Thread.currentThread().getName() +
" consuming " + item);

if (queue.size() == (capacity - 1)) {
notifyAll();
}

return item;
}
}

public class ProducerConsumer {
private static class Producer implements Runnable {
private MyQueue queue;
private Random random = new Random();

public Producer(MyQueue queue) {
this.queue = queue;
}

public void run() {
try {
for (;;) {
queue.enqueue(random.nextInt());
Thread.sleep((int)(Math.random() * 3000) + 1000);
}
} catch (InterruptedException ex) {
System.out.println(Thread.currentThread().getName() +
" interrupted");
}
}
}

private static class Consumer implements Runnable {
private MyQueue queue;

public Consumer(MyQueue queue) {
this.queue = queue;
}

public void run() {
try {
for (;;) {
queue.dequeue();
Thread.sleep((int)(Math.random() * 5000) + 3000);
}
} catch (InterruptedException ex) {
System.out.println(Thread.currentThread().getName() +
" interrupted");
}
}
}

public static void main(String[] args) {
MyQueue queue = new MyQueue(10);

new Thread(new Producer(queue), "Producer 1").start();
new Thread(new Producer(queue), "Producer 2").start();
new Thread(new Consumer(queue), "Consumer 1").start();
new Thread(new Consumer(queue), "Consumer 2").start();
}
}

示例输出:

$ java ProducerConsumer
Thread Producer 1 producing 1380029295
Thread Consumer 1 consuming 1380029295
Thread Producer 2 producing 1449212482
Thread Consumer 2 consuming 1449212482
Thread Producer 2 producing -1845586946
Thread Producer 1 producing -1072820603
Thread Producer 1 producing 1224861300
Thread Producer 2 producing 507431251
Thread Consumer 2 consuming -1845586946
Thread Consumer 1 consuming -1072820603
Thread Producer 2 producing -1305630628
Thread Producer 1 producing 1413011254
Thread Producer 2 producing -222621018
Thread Consumer 2 consuming 1224861300
Thread Producer 1 producing -1628544536
Thread Consumer 1 consuming 507431251

关于java - 使用 Java(同步)但始终运行相同线程的生产者/消费者模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33195290/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com