首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >出厂线程和使用者线程意外地工作

出厂线程和使用者线程意外地工作
EN

Stack Overflow用户
提问于 2021-08-04 14:01:58
回答 1查看 97关注 0票数 0

主线程

代码语言:javascript
复制
 public static void main(String[] args) {
        List<Integer> taskQueue = new ArrayList<Integer>();
        int MAX_CAPACITY = 5;
        Producer pt=new Producer(taskQueue,MAX_CAPACITY);
        Consumer ct=new Consumer(taskQueue);
        pt.start();
        ct.start();
    }

生产者线程

代码语言:javascript
复制
public class Producer<T> extends Thread {

    private final List<Integer> taskQueue;
    private final int Max_CAPACITY;

    public Producer(List<Integer> taskQueue,int size) {
        this.taskQueue = taskQueue;
        this.Max_CAPACITY=size;
    }

    @Override
    public void run() {
        int count = 0;
        while (true) {
            try {
                produce(count++);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void produce(int i) throws InterruptedException {

        synchronized (taskQueue){
            while(taskQueue.size()==Max_CAPACITY){
                System.out.println("taskQueue is full wait some time for removal");
                taskQueue.wait();
            }

            Thread.sleep(100);
            taskQueue.add(i);

            System.out.println("produced "+i);
            taskQueue.notifyAll();
        }
    }
}

消费线程

代码语言:javascript
复制
public class Consumer<T> extends Thread {

    private final List<Integer> taskQueue;

    Consumer(List<Integer> taskQueue) {
        this.taskQueue = taskQueue;

    }

    @Override
    public void run() {

        while (true) {
            try {
                consume();
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }

    private void consume() throws InterruptedException {
        synchronized (taskQueue) {

            while(taskQueue.isEmpty()){
                System.out.println("taskQueue is empty..wait for adding items");
                taskQueue.wait();
            }
            Thread.sleep(100);
           int removal= taskQueue.remove(0);
            System.out.println("consumed.. "+removal);
            taskQueue.notifyAll();


        }
    }
}

根据这一概念:

Wait()notify()方法是在object.Here上调用的,taskqueue是常见的对象。假设Producer线程首先获得了机会,并获得了taskqueue对象的锁。在taskqueue中添加值时,它调用notifyAll().But,在Consumer线程上不调用wait() (因为队列不是空的),因此notifyAll()对消费者没有用处。同样,假设使用者将从taskqueue中恢复并删除元素并调用notifyAll(),现在producer线程没有使用使用者notifyAll(),因为生产者上也没有调用wait()。那么这个生产者-消费者是如何运作的呢?

简单地说,如果生产者没有调用,那么即使使用者线程调用了notifyAll(),生产者线程也是如何恢复工作的。如果生产者中没有调用wait(),那么生产者是如何得到消费者线程通知的?

产出:

代码语言:javascript
复制
produced 0
produced 1
produced 2
produced 3
produced 4
taskQueue is full wait some time for removal
consumed.. 0
consumed.. 1
consumed.. 2
consumed.. 3
consumed.. 4
taskQueue is empty..wait for adding items
produced 5
produced 6
produced 7
produced 8
produced 9
taskQueue is full wait some time for removal
consumed.. 5
consumed.. 6
consumed.. 7
consumed.. 8
consumed.. 9

会一直这样下去的..。

更新:

假设生产者线程先得到了机会。然后打印(生产)

代码语言:javascript
复制
produced 0
produced 1
produced 2
produced 3
produced 4

在此之后,taskequeue变得满了,wait()被调用到producer上,所以现在使用者线程获得了机会,并且一旦使用者线程使用了元素consume 0notify()被调用,所以现在处于等待状态的生产者线程获得通知和恢复。所以现在生产者应该生产5种产品6种等等。,但是使用者线程仍然在运行和打印

代码语言:javascript
复制
consume 2
consume 3

这是怎么回事?希望现在明白我的意思了。所有我想要的这个输出的理由。如何打印

EN

回答 1

Stack Overflow用户

发布于 2021-08-04 14:09:08

notifyAll总是会立即返回。( notify也是如此)。

notifyAll --它将“突破”在同一个对象上调用wait的任何东西,但这并不意味着这些线程立即继续运行obj.wait()调用之后的代码。如果没有这样的线程,那么什么都不会发生。

notify是一回事,除了没有把它们全部消灭,它打破了一个任意的,如果没有,那么什么都不会发生。

其他线程没有立即开始运行的原因是,它们首先需要重新获取锁(它们位于一个synchronized(obj)块中;当等待启动时,它们会“丢弃”该锁,它们需要在等待结束之前重新获取锁。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68652663

复制
相关文章

相似问题

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