• 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();
            }
    
        }
    }
  • 相关阅读:
    TCP协议简单套接字通信 客户端
    TCP协议简单套接字通信 服务端
    java课程作业--动手动脑
    Java方法课程作业1,2,3
    java猜数字(实验任务五)
    课程作业02(关于Java的几点讨论)
    java多个int型数据累加求和
    java基本登录界面
    大道至简第一章观后感——java伪代码
    《大道至简—软件编程者的思想》观后感
  • 原文地址:https://www.cnblogs.com/jdflyfly/p/3891550.html
Copyright © 2020-2023  润新知