java 生产者与消费者问题

 

 

分别利用 锁、信号量、同步监视器实现了生产者消费者问题。

 

package thread;

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Item {
    int id;

    public Item(int id) {
        this.id = id;
    }

    public String toString() {
        return "[item " + id + "]";
    }
}

abstract class Buffer {
    int capacity;
    Item[] items;
    int count;
    int in, out;

    public Buffer(int capacity) {
        this.capacity = capacity;
        items = new Item[capacity];
        count = 0;
        in = out = 0;
    }

    abstract void put(Item item);

    abstract Item get();

    public void printBuf() {
        System.out.print("current buf status: [ ");
        for (int i = 0; i < capacity; i++) {
            System.out.print(items[i] + " ");
        }
        System.out.print("] ");
        System.out.print("count:" + count + " ");
        System.out.print("in:" + in + " out:" + out + " ");
        System.out.println();
    }
}

/**
 * 利用锁实现线程同步的buffer
 * 
 * @author jd
 * 
 */
class LockBuffer extends Buffer {

    Lock lock = new ReentrantLock();
    Condition empty = lock.newCondition();
    Condition full = lock.newCondition();

    public LockBuffer(int capacity) {
        super(capacity);
    }

    public void put(Item item) {
        lock.lock();

        try {
            while (count == capacity)
                full.await();
            items[in] = item;
            in = (in + 1) % capacity;
            count++;
            empty.signal();

            System.out.println(Thread.currentThread().getName() + " put item " + item.id);
            printBuf();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        finally {
            lock.unlock();
        }
    }

    public Item get() {
        lock.lock();
        Item res = null;
        try {
            while (count == 0)
                empty.await();
            res = items[out];
            items[out] = null;
            out = (out + 1) % capacity;
            count--;
            full.signal();

            System.out.println(Thread.currentThread().getName() + " get item " + res.id);
            printBuf();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return res;
    }

}

/**
 * 利用信号量实现的线程同步的buffer
 * 
 * @author jd
 * 
 */
class SemaphoreBuffer extends Buffer {
    Semaphore mutex;
    Semaphore full;
    Semaphore empty;

    public SemaphoreBuffer(int capacity) {
        super(capacity);
        mutex = new Semaphore(1);
        full = new Semaphore(0);
        empty = new Semaphore(capacity);
    }

    public void put(Item item) {

        try {
            empty.acquire();
            mutex.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        items[in] = item;
        in = (in + 1) % capacity;
        count++;

        System.out.println(Thread.currentThread().getName() + " put item " + item.id);
        printBuf();

        mutex.release();
        full.release();

    }

    public Item get() {

        try {
            full.acquire();
            mutex.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Item res = items[out];
        items[out] = null;
        out = (out + 1) % capacity;
        count--;

        System.out.println(Thread.currentThread().getName() + " get item " + res.id);
        printBuf();

        mutex.release();
        empty.release();
        return res;
    }

}

/**
 * 利用同步监视器实现的线程同步的buffer
 * 
 * @author jd
 * 
 */
class MonitorBuffer extends Buffer {

    public MonitorBuffer(int capacity) {
        super(capacity);
    }

    public void put(Item item) {
        synchronized (this) {

            try {
                while (count == capacity)
                    wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            items[in] = item;
            in = (in + 1) % capacity;
            count++;
            notifyAll();

            System.out.println(Thread.currentThread().getName() + " put item " + item.id);
            printBuf();

        }
    }

    public Item get() {
        synchronized (this) {
            try {
                while (count == 0)
                    wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            Item res = items[out];
            items[out] = null;
            out = (out + 1) % capacity;
            count--;
            notifyAll();

            System.out.println(Thread.currentThread().getName() + " get item " + res.id);
            printBuf();
            return res;
        }
    }
}

class Producer implements Runnable {
    Buffer buf;
    Random rand = new Random();

    public Producer(Buffer buf) {
        this.buf = buf;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            Item item = new Item(rand.nextInt(100));
            buf.put(item);

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

class Consumer implements Runnable {
    Buffer buf;

    public Consumer(Buffer buf) {
        this.buf = buf;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            Item item = buf.get();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class BoundedBufferTest {

    public static void main(String[] args) {
        // Buffer buf = new LockBuffer(5);
        // Buffer buf = new SemaphoreBuffer(5);
        Buffer buf = new MonitorBuffer(5);

        // 3个生产者,3个消费者,每个生产或者消费10次。
        for (int i = 0; i < 3; i++) {
            new Thread(new Producer(buf), "p" + i).start();
            new Thread(new Consumer(buf), "c" + i).start();
        }

    }
}

 

posted @ 2014-08-05 09:43  jdflyfly  阅读(284)  评论(0编辑  收藏  举报