首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我从同一个线程获得连续的结果时,“同步”会做什么?

当我从同一个线程获得连续的结果时,“同步”会做什么?
EN

Stack Overflow用户
提问于 2020-05-24 13:22:46
回答 1查看 98关注 0票数 0

我试着为生产者和消费者做一些练习。下面的代码是线程安全的,但是这段代码不能解决生产者和使用者之间的同步问题。

代码语言:javascript
复制
package edu.seu.juc.pac;

import edu.seu.juc.annotation.ThreadSafe;

@ThreadSafe
public class TestProducerAndConsumer {
    public static void main(String[] args) {
        Clerk clerk = new Clerk();

        Producer producer = new Producer(clerk);
        Consumer consumer = new Consumer(clerk);

        new Thread(producer, "producer A").start();
        new Thread(consumer, "consumer B").start();
    }


    private static class Clerk {
        private int product = 0;

        public synchronized void get() {
            if (product >= 10) {
                System.out.println("product is full");
            } else {
                System.out.println(Thread.currentThread().getName() + " produce: " + (++product));
            }
        }

        public synchronized void sale() {
            if (product <= 0) {
                System.out.println("product is lack");
            } else {
                System.out.println(Thread.currentThread().getName() + " consume: " + (--product));
            }
        }
    }

    private static class Producer implements Runnable {
        private Clerk clerk;

        public Producer(Clerk clerk) {
            this.clerk = clerk;
        }

        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                clerk.get();
            }
        }
    }

    private static class Consumer implements Runnable {
        private Clerk clerk;

        public Consumer(Clerk clerk) {
            this.clerk = clerk;
        }

        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                clerk.sale();
            }
        }
    }
}

真结果

代码语言:javascript
复制
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
product is full
product is full
product is full
product is full
product is full
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0
product is lack
product is lack
product is lack
product is lack
product is lack

在我看来,结果可能如下所示--例如,--我的预期结果之一

代码语言:javascript
复制
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0

volatile一定做了些什么。有人能告诉我搜索的原因或关键词吗。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-24 17:52:27

我认为当“产品满了”时,生产者应等待消费者消费产品,当“产品不足”时,消费者应等待生产者生产产品。通过这种方式,这两个线程将“串联”工作,而现在它们“按顺序”工作。

这可以很容易地使用wait()notify()方法。

使用wait()notifyAll()更改wait()类以实现“等待”将导致预期的输出:

代码语言:javascript
复制
private static class Clerk {
        private int product = 0;

        public synchronized void get() {
                while (product >= 5) {
                        try {
                                wait();
                        } catch (Exception e) {
                                e.printStackTrace();
                                continue;
                        }
                }
                System.out.println(Thread.currentThread().getName() + " produce: " + (++product));
                notifyAll();
        }

        public synchronized void sale() {
                while (product <= 0) {
                        try {
                                wait();
                        } catch (Exception e) {
                                e.printStackTrace();
                                continue;
                        }
                }
                System.out.println(Thread.currentThread().getName() + " consume: " + (--product));
                notifyAll();
        }
}

代码语言:javascript
复制
$ javac TestProducerAndConsumer.java
$ java TestProducerAndConsumer
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0

编辑

,但对于这个问题,我对同一线程的连续结果表示怀疑。好像是按顺序工作的。

我认为这是因为生产者和消费者在循环中运行,当“它是生产者转向”时,它重新获得对象的锁,然后消费者才有机会这样做(反之亦然)。

如果我们在每个Thread.sleep(1).get().sale()之后添加一个1毫秒的.get(),那么输出中就会出现“混合”结果:

代码语言:javascript
复制
private static class Producer implements Runnable {
        private Clerk clerk;

        public Producer(Clerk clerk) {
                this.clerk = clerk;
        }

        @Override
        public void run() {
                for (int i = 0; i < 10; i++) {
                        clerk.get();
                        try {
                                Thread.sleep(1);
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                }
        }
}

private static class Consumer implements Runnable {
        private Clerk clerk;

        public Consumer(Clerk clerk) {
                this.clerk = clerk;
        }

        @Override
        public void run() {
                for (int i = 0; i < 10; i++) {
                        clerk.sale();
                        try {
                                Thread.sleep(1);
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                }
        }
}

代码语言:javascript
复制
$ javac TestProducerAndConsumer.java
$ java TestProducerAndConsumer
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61986582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档