在Java中具有重入锁和条件的Producer Consumer场景 [英] Producer Consumer scenario with Reentrant Lock and Condition in Java

查看:76
本文介绍了在Java中具有重入锁和条件的Producer Consumer场景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用重入锁和条件编写了生产者消费者程序.它工作正常,但是我不确定实施是否正确.而且,它似乎不是最佳的.可以请人确认这是否是正确的实现,还可以告诉您如何对其进行优化,例如-在真正需要的地方锁住

I have written a Producer Consumer program using Reentrant Lock and condition. It is working correctly, but I am not very sure whether implementation is correct. Moreover it does not seem to be optimal. Can somebody please verify if this is a correct implementation, moreover can you please tell, how to optimize it, like - taking lock at the place where it is really required

public class TestRL {

static class Observed {
    boolean filled = false;

    public void setFilled(boolean filled) {
        this.filled = filled;
    }

    public boolean getFilled() {
        return filled;
    }
}

static Observed observed = new Observed();

static class Consumer implements Runnable {
    Observed observed;
    ReentrantLock lock;
    Condition condition;

    Consumer(Observed observed, ReentrantLock lock, Condition condition) {
        this.observed = observed;
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        lock.lock();
        try {
            for (int i = 0; i < 20; i++) {
                if (observed.getFilled() == false) {
                    try {
                        System.out.println("consumer waiting");
                        condition.await();
                        System.out.println("consumed");

                        Thread.sleep(400 + 1000 * i % 2);
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                    observed.setFilled(false);
                    condition.signalAll();
                }else{
                    observed.setFilled(false);
                    condition.signalAll();
                }
            }
        } finally {
            lock.unlock();
        }

    }
}

static class Producer implements Runnable {
    Observed observed;
    ReentrantLock lock;
    Condition condition;

    Producer(Observed observed, ReentrantLock lock, Condition condition) {
        this.observed = observed;
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        lock.lock();
        try {
            for (int i = 0; i < 20; i++) {
                if (observed.getFilled() == true) {
                    try {
                        System.out.println("producer waiting");
                        condition.await();
                        System.out.println("produced");
                        Thread.sleep(1000);
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                    observed.setFilled(true);
                    condition.signalAll();
                }else{
                    observed.setFilled(true);
                    condition.signalAll();
                }
            }
        } finally {
            lock.unlock();
        }

    }
}

/**
 * @param args
 */
public static void main(String[] args) {
    ReentrantLock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    Producer producer = new Producer(observed, lock, condition);
    Consumer consumer = new Consumer(observed, lock, condition);
    Thread t1 = new Thread(producer);
    Thread t2 = new Thread(consumer);
    t1.start();
    t2.start();

}

}

推荐答案

以下是使用ReentrantLock&健康)状况.万一有人要,以防万一.

Following is one more sample code for producer-consumer problem using ReentrantLock & Condition. Just in case if someone wants.

package reentrant_prodcons;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Reentrant_ProdCons {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here

        Queue<Integer> queue=new LinkedList<Integer>();
        ReentrantLock lock=new ReentrantLock();
        Condition con=lock.newCondition();
        final int size = 5;

        new Producer(lock, con, queue, size).start();
        new Consumer(lock, con, queue).start();

    }

}


class Producer extends Thread{

    ReentrantLock  lock;
    Condition con;
    Queue<Integer> queue;
    int size;

    public Producer(ReentrantLock lock, Condition con, Queue<Integer> queue, int size) {
        this.lock = lock;
        this.con = con;
        this.queue = queue;
        this.size=size;
    }


    public void run(){
        for(int i=0;i<10;i++){
            lock.lock();
            while(queue.size()==size){
                try {
                    con.await();
                } catch (InterruptedException ex) {
                    Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            queue.add(i);
            System.out.println("Produced : "+i);
            con.signal();
            lock.unlock();
        }
    }

}

class Consumer extends Thread{


    ReentrantLock lock;
    Condition con;
    Queue<Integer> queue;


    public Consumer(ReentrantLock lock, Condition con, Queue<Integer> queue) {
        this.lock = lock;
        this.con = con;
        this.queue = queue;
    }

    public void run(){
        for(int i=0;i<10;i++){
           lock.lock();
           while(queue.size()<1){
               try {
                   con.await();
               } catch (InterruptedException ex) {
                   Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
               }
           }
            System.out.println("Consumed : "+queue.remove());
            con.signal();
            lock.unlock();
        }
    }
}

这篇关于在Java中具有重入锁和条件的Producer Consumer场景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆