繁体   English   中英

wait()/ notify()无法正常工作

[英]wait()/notify() not working properly

我有一个ConsumerProducer对象,我想从两个不同的线程获取锁。 课程如下:

public class ConsumerProducer {

    public String stringPool = null;

    public void put(String s){
        stringPool = s;
    }

    public String get(){
        String ret = stringPool;
        stringPool = null;
        return ret;
    }

}

线程impl类如下:

public class WaitNotifyTest implements Runnable {

    private String threadType;
    public ConsumerProducer cp;
    public static volatile int i = 1;

    public WaitNotifyTest(String threadType, ConsumerProducer cp) {
        this.threadType = threadType;
        this.cp = cp;
    }

    public static void main(String[] args) throws InterruptedException {

        ConsumerProducer cp = new ConsumerProducer();
        WaitNotifyTest test1 = new WaitNotifyTest("Consumer", cp);
        WaitNotifyTest test2 = new WaitNotifyTest("Producer", cp);

        Thread t1 = new Thread(test1);
        Thread t2 = new Thread(test2);

        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }

    @Override
    public void run() {
        while (true) {

            if (threadType.equalsIgnoreCase("Consumer")) {
                synchronized (cp) {
                    try {
                        if (null != cp.get()) {
                            cp.wait();
                        }
                        consume();
                        System.out.println("notify from Consumer");
                        cp.notify();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            } else {
                synchronized (cp) {
                    try {
                        if (null == cp.get()) {
                            cp.wait();
                        }
                        produce();
                        System.out.println("notify from Producer");
                        cp.notify();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            if (i == 5) {
                break;
            }
            i++;
        }
    }

    public void consume() {
        System.out.println("Putting: Counter" + i);
        cp.put("Counter" + i);
    }

    public void produce() {
        System.out.println("getting: " + cp.get());
    }

}

但是,当我运行代码时,它面临着某种死锁,它就像是打印一样

Putting: Counter3
notify from Consumer

有些事情发生了严重错误,但我无法确定。 请帮忙。

你的消费者正在做生产者的工作,生产者正在做消费者的工作。 交换责任并修改条件等。 请参阅下面的代码。

  1. 消费者会在没有任何东西可以等待的时候等待他释放cp的锁定。 这样生产者就有机会进入同步区块。
  2. 制片人只在没有任何东西时才会制作,否则他会等待。 之后,他将释放cp的锁定。 这样消费者就有机会进入同步区块。
  3. 消费者是让事情消失的人。
  4. 制片人是把事情放在桌面上的人。
  5. 根据你的评论。 你想把Counter从1改为5,所以你应该只在Producer线程中添加i ++。 如何控制两个线程的增加?
  6. 您不判断它是消费者还是生产者从cp对象调用get() ,而是将null stringPool 这显然是错误的,并且会使消费者从公共空间中获得空位。 我添加了一个新方法clearString() ,它将公共空间设置为null,只有当消费者使用了产品时。

     public class WaitNotifyTest implements Runnable { private String threadType; public ConsumerProducer cp; public static volatile int i = 0; public WaitNotifyTest(String threadType, ConsumerProducer cp) { this.threadType = threadType; this.cp = cp; } public static void main(String[] args) throws InterruptedException { ConsumerProducer cp = new ConsumerProducer(); WaitNotifyTest test1 = new WaitNotifyTest("Consumer", cp); WaitNotifyTest test2 = new WaitNotifyTest("Producer", cp); Thread t1 = new Thread(test1); Thread t2 = new Thread(test2); t1.start(); t2.start(); t1.join(); t2.join(); } @Override public void run() { while (true) { if (threadType.equalsIgnoreCase("Consumer")) { synchronized (cp) { try { /* * Consumer will wait when there is nothing to get and he will release the lock of cp. * So that producer has change to go into the synchronized block. */ if (null == cp.get()) { cp.wait(); } consume(); System.out.println("notify from Consumer"); cp.notify(); } catch (InterruptedException e) { e.printStackTrace(); } } } else { synchronized (cp) { try { /* * Producer only produce when there is nothing or he will wait. At the same time, he will release the lock of cp. * So that consumer has chance to go into the synchronized block. */ if (null != cp.get()) { cp.wait(); } i++; produce(); System.out.println("notify from Producer"); cp.notify(); } catch (InterruptedException e) { e.printStackTrace(); } } } if (i == 5) { break; } } } public void consume() { System.out.println("getting: " + cp.get()); cp.clearString(); } public void produce() { System.out.println("Putting: Counter" + i); cp.put("Counter" + i); }} 

另请参阅ConsumerProducer类。

public class ConsumerProducer {
        public String stringPool = null;

        public void put(String s){
            stringPool = s;
        }

        public String get(){
            return stringPool;
        }

        public void clearString(){
            stringPool = null;
        }
}

更新的代码在这里:ConsumerProducer.java:
公共类ConsumerProducer {

    public volatile String stringPool = null;

    public void put(String s){
        this.stringPool = s;
    }

    public String get(){
        String ret = this.stringPool;
        //this.stringPool = null;
        return ret;
    }
    //added
    public void clearString(){
        this.stringPool = null;
    }

}

WaitNotifyTest.java公共类WaitNotifyTest实现Runnable {

    private String threadType;
    public ConsumerProducer cp;
    public static volatile int i = 0;

    public WaitNotifyTest(String threadType, ConsumerProducer cp) {
        this.threadType = threadType;
        this.cp = cp;
    }

    public static void main(String[] args) throws InterruptedException {

        ConsumerProducer cp = new ConsumerProducer();
        WaitNotifyTest test1 = new WaitNotifyTest("Consumer", cp);
        WaitNotifyTest test2 = new WaitNotifyTest("Producer", cp);

        Thread t1 = new Thread(test1);
        Thread t2 = new Thread(test2);

        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }

    @Override
    public void run() {
        while (true) {

            if (threadType.equalsIgnoreCase("Consumer")) {
                synchronized (cp) {
                    try {
                        if (null == cp.get()) {
                            cp.wait();
                        }
                        consume();
                        System.out.println("notify from Consumer");
                        cp.notify();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            } else {
                synchronized (cp) {
                    try {
                        if (null != cp.get()) {
                            cp.wait();
                        }
                        i++;
                        produce();
                        System.out.println("notify from Producer");
                        cp.notify();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            if (i == 5) {
                break;
            }

        }
    }

    public void produce() {
        System.out.println("Putting: Counter" + i);
        cp.put("Counter" + i);
    }

    public void consume() {
        System.out.println("getting: " + cp.get());
        cp.clearString();
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM