Реализация условия блокировки Java - PullRequest
0 голосов
/ 29 июня 2019

Нужна помощь с кодом по ссылке ниже, так как он должен работать бесконечно аналогично с любой типичной проблемой производителя / потребителя, но каким-то образом он застревает при вызове condition.signal (). Что я тут не так делаю?

В основном методе я создал два потока, один - потребитель, а другой - производитель. у него есть общая очередь задач, где оба обновляют запись.

package com.anurgup.handson;

import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionService implements Runnable {

    Lock lock = new ReentrantLock();
    Condition added = lock.newCondition();
    Condition removed = lock.newCondition();

    // type of service
    String type;

    // shared task for insertion and deletion of task
    static Queue<Integer> task = new PriorityQueue<Integer>();

    // max number of task allowed
    private static final int MAX_SIZE = 5;

    public ConditionService(String type) {
        this.type = type;
    }

    public static void main(String[] args) {

        ExecutorService service = Executors.newFixedThreadPool(2);
        service.submit(new ConditionService("producer"));
        service.submit(new ConditionService("consumer"));

    }

    public void produce() {
        try {
            while (true) {
                System.out.println("in producer...");
                synchronized (task) {
                    while (task.size() == MAX_SIZE)
                        removed.await();
                    System.out.println("added item: " + task.size());
                    task.add(task.size());
                    added.signal();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void consume() {
        try {
            while (true) {
                System.out.println("in consumer...");
                synchronized (task) {
                    while (task.isEmpty())
                        added.await();
                    System.out.println("removed item: " + task.peek());
                    task.remove();
                    removed.signal();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        if (this.type.equals("producer"))
            this.produce();
        else
            this.consume();
    }
}

1 Ответ

1 голос
/ 29 июня 2019

Вы делаете две ошибки.Во-первых, ваша блокировка и условия должны быть статическими, иначе каждая задача будет только синхронизироваться и ждать сама.Во-вторых, вам нужно использовать lock.lock(), а не synchronized.Это должно выглядеть так:

lock.lock();
try {
    // wait
    // produce/consume
} finally {
    lock.unlock();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...