java - Java 中多线程同步不起作用

标签 java multithreading

我正在尝试 java 中的多线程示例。 Java Complete引用第七版中有一个关于多线程同步的例子。该示例运行良好。但是当我稍微添加一行来创建同一类的另一个线程时,这不起作用。有人可以让我知道为什么会发生这种情况吗?下面给出了示例。下面的代码是生产者和消费者的经典示例。当只有一个生产者时它工作得很好,当我有两个生产者时它就会失败。它只是一直到 15 并停止。

class Q {

    int n;
    boolean valueSet = false;

    synchronized int get() {
        while (!valueSet) {
            try {
                wait();
            } catch (InterruptedException e) {
                System.out.println("InterruptedException caught");
            }
        }
        System.out.println("Got: " + n);
        valueSet = false;
        notify();
        return n;
    }

    synchronized void put(int n) {
        while (valueSet) {
            try {
                wait();
            } catch (InterruptedException e) {
                System.out.println("InterruptedException caught");
            }
        }
        this.n = n;
        valueSet = true;
        System.out.println("Put: " + n);
        notify();
    }
}

class Producer implements Runnable {

    Q q;

    Producer(Q q) {
        this.q = q;
        new Thread(this, "Producer").start();
        //new Thread(this, "Producer2").start();
    }

    public void run() {
        int i = 0;
        while (true) {
            q.put(i++);
        }
    }
}

class Consumer implements Runnable {

    Q q;

    Consumer(Q q) {
        this.q = q;
        new Thread(this, "Consumer").start();
    }

    @Override
    public void run() {
        while (true) {
            q.get();
        }
    }
}

public class PCFixed {

    public static void main(String[] args) {
        Q q = new Q();
        Producer P1 = new Producer(q);
        new Consumer(q);
        Producer P2 = new Producer(q);
        System.out.println("Press Control-C to stop.");
    }
}

最佳答案

Q 被写入为一次仅接受一个值。您需要将 put 更改为 boolean 方法 - 如果 valueset 为 true,则返回 true,然后正常进行;如果 valueset 为 false,则返回 false 并返回而不执行任何操作。然后调用 put 的方法将需要不断重试,直到获得真正的响应。这样多个消费者就可以使用同一个Q对象,而不会互相干扰。

如果您使用多个生产者,更好的解决方案是使用 ConcurrentLinkedQueue ,这是一个线程安全的队列。生产者将向队列提供整数,而消费者将向队列轮询整数。多个生产者可以同时提供整数而不会互相干扰,多个消费者也可以同时轮询整数而不会互相干扰。

关于java - Java 中多线程同步不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15982403/

相关文章:

java - 在java中加载的图像上绘制对象

java - 将对象从一个私有(private)方法传递到另一个私有(private)方法

Java线程: wait,notifyAll和synchronized关键字没有按预期工作

c# - 为什么任务的结果属性对于非泛型任务 (C# 4.0+) 不可用?

java - applicationContext.xml bean 的 swing 编辑器 ui?

java - 启动第二个 Activity 而不是第一个 android

java - Spark 找不到 Scala 特定方法

java - synchronized 是否像 Lock.lock() 那样停放并发线程?

java - 从线程的内部线程启动 android Activity 。

c++ - : non-blocking write, 假想的锁机制读取并失效