gpt4 book ai didi

java - Java线程生产者和使用者

转载 作者:行者123 更新时间:2023-12-03 13:09:26 25 4
gpt4 key购买 nike

我正在编写一个使用ReentrantLock而不是生产者和消费者问题的synchronized的小程序。但是程序被卡住了,因为一旦消费了生产的商品,消费线程将停止并且永远不会恢复消费。

程式码片段:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Mantou2 {
int id;

public Mantou2(int id) {
this.id = id;
}}

class Basket2 {
final int max = 20;
Mantou2[] ms;
int n;
Lock lock;
Condition full;
Condition empty;

public Basket2() {
ms = new Mantou2[max];
n = 0;

lock = new ReentrantLock();
full = lock.newCondition();
empty = lock.newCondition();
}

public void consume() {
lock.lock();

try {
while (n == 0) {
System.out.println("No Mantou left!");
empty.await();
}

empty.signal();
System.out.println(ms[--n].id + " consumed and " + n + " left");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}

}

public void produce() {
lock.lock();
try {
while (n == max) {
System.out.println("Inventory is full!");
full.await();
}

full.signal();
ms[n] = new Mantou2(n++);
System.out.println(ms[n - 1].id + " produced and " + n + " left");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}}

class Consumer2 implements Runnable {
Basket2 basket;

public Consumer2(Basket2 basket) {
this.basket = basket;
}

@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 50; i++) {
basket.consume();
try {
Thread.sleep((long) (Math.random() * 300));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}}

class Producer2 implements Runnable {
Basket2 basket;

public Producer2(Basket2 basket) {
this.basket = basket;
}

@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 50; i++) {
basket.produce();
try {
Thread.sleep((long) (Math.random() * 300));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}}

public class ProducerCustomer2 {

public static void main(String[] args) {
// TODO Auto-generated method stub
Basket2 basket = new Basket2();
Producer2 producer = new Producer2(basket);
Consumer2 consumer = new Consumer2(basket);
Thread p = new Thread(producer);
Thread c = new Thread(consumer);
p.start();
c.start();
}}

最佳答案

好的,您忘了做两件事:

  • 在消费和产生
  • 时更新变量n
  • 消耗后从列表中删除Mantou(这很难用列表完成,因此我建议改用ArrayList)

  • 另外,您不需要两个条件……您可以只用一个条件就可以。这是工作代码:
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    import java.util.ArrayList;

    public class ProducerCustomer2 {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    ProducerCustomer2 pc = new ProducerCustomer2();
    pc.start();
    }

    public void start() {
    Basket2 basket = new Basket2();
    Producer2 producer = new Producer2(basket);
    Consumer2 consumer = new Consumer2(basket);
    Thread p = new Thread(producer);
    Thread c = new Thread(consumer);
    p.start();
    c.start();
    }

    private class Mantou2 {
    int id;

    public Mantou2(int id) {
    this.id = id;
    }
    }

    private class Basket2 {
    final int max = 20;
    ArrayList<Mantou2> ms;
    int n;
    Lock lock;
    Condition full;
    Condition empty;

    public Basket2() {
    ms = new ArrayList<Mantou2>();
    n = 0;

    lock = new ReentrantLock();
    full = lock.newCondition();
    empty = lock.newCondition();
    }

    public void consume() {
    lock.lock();

    try {
    while (n == 0) {
    System.out.println("No Mantou left!");
    full.await();
    }
    System.out.println(ms.get(n-1).id + " consumed and " + n + " left");
    ms.remove(n-1);
    n--;
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } finally {
    full.signal();
    lock.unlock();
    }

    }

    public void produce() {
    lock.lock();
    try {
    while (n == max) {
    System.out.println("Inventory is full!");
    full.await();
    }
    n++;
    ms.add(new Mantou2(n));
    System.out.println(ms.get(n-1).id + " produced and " + n + " left");
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } finally {
    full.signal();
    lock.unlock();
    }
    }
    }

    private class Consumer2 implements Runnable {
    Basket2 basket;

    public Consumer2(Basket2 basket) {
    this.basket = basket;
    }

    @Override
    public void run() {
    // TODO Auto-generated method stub
    for (int i = 0; i < 50; i++) {
    basket.consume();
    try {
    Thread.sleep((long) (Math.random() * 300));
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }

    private class Producer2 implements Runnable {
    Basket2 basket;

    public Producer2(Basket2 basket) {
    this.basket = basket;
    }

    @Override
    public void run() {
    // TODO Auto-generated method stub
    for (int i = 0; i < 50; i++) {
    basket.produce();
    try {
    Thread.sleep((long) (Math.random() * 300));
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }
    }

    关于java - Java线程生产者和使用者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39715500/

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