我有两个主题。一个是生产者(for i in range(0, cols):
for j in range(0, rows):
x = np.append(a[i][j], b, axis = 1)
),第二个是消费者(class Deliver
)。我想模仿门生产者。因此,生产者提供消费者可以生产门的木材。但我真的不知道如何在这两个线程之间进行通信。现在,当我运行我的程序时,只交付木材但不生产门。我不明白为什么。
class Produce
答案 0 :(得分:1)
现在,当我运行我的程序时,只交付木材但不生产门。我不明白为什么
您的代码存在多个问题:
synchronized
时,进入该方法的任何线程都将获得this
上的锁定(即调用该方法的实例)。由于this
中的Deliver
引用了Deliver
个实例,this
中的Produce
引用了Produce
个实例,wait
和notify
调用在这种情况下几乎没用,因为他们对相同的对象不感兴趣。Deliver
和Produce
都将修改Integer
传递给他们的同一main
,但事实并非如此。那就是说,我强烈建议您考虑使用像ArrayBlockingQueue
之类的东西来解决这个问题,而不是使用wait
和notify
重新发明轮子。
答案 1 :(得分:0)
更改
if (wood == 10) {
到
if (wood >= 10) {
如果线程在== 10
时没有捕获它答案 2 :(得分:0)
需要注意的是Integer是不可变的。
当您更改对整数的引用时,您正在创建一个与前一个对象无关的新对象。
你想要这个在两个线程之间共享的对象,所以当你改变值(而不是引用)时,它们会看到相同的值。
e.g。
wood -= 10;
与
相同wood = Integer.valueOf(wood.intValue() - 10);
我建议您使用AtomicInteger
并对其final
进行引用,以确保您不会意外尝试更改参考。
安德鲁詹金斯建议;如果你锁定,通知/等待不相关的对象,你就没有任何线程安全。拥有共享对象后,您必须锁定,通知/等待该共享对象。
答案 3 :(得分:0)
考虑到Peter Lawrey关于使用AtomicInteger的建议,我会把我的解决方案放到混合中。
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) {
AtomicInteger wood = new AtomicInteger(0);
new Deliver(wood);
new Produce(wood);
}
}
public class Deliver implements Runnable {
private static int MAX_STOCKPILE = 15;
private final AtomicInteger wood;
public Deliver(AtomicInteger wood) {
this.wood = wood;
new Thread(this, "Deliver").start();
}
public void deliver() throws InterruptedException{
Thread.sleep(500);
synchronized(wood) {
if (wood.intValue() < MAX_STOCKPILE) {
wood.addAndGet(1);
System.out.println("Wood delivered" + " | Wood stockpile: " + wood);
wood.notify();
} else {
wood.wait();
}
}
}
@Override
public void run() {
while (true) {
try {
deliver();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Produce implements Runnable{
private final AtomicInteger wood;
public Produce(AtomicInteger wood) {
this.wood = wood;
new Thread(this, "Produce").start();
}
public void produce() throws InterruptedException{
synchronized(wood) {
if (wood.intValue() >= 10) {
wood.addAndGet(-10); //produce
System.out.println("Doors produced");
wood.notify();
}
else {
wood.wait();
}
}
}
@Override
public void run() {
while (true) {
try {
produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
主要变化: