需要检查生产者/消费者任务解决方案

时间:2012-04-04 22:48:05

标签: java multithreading

我已经通过几种方式解决了P / C问题。任何人都可以检查它们的正确性吗? 提前谢谢。

1)的BlockingQueue

public static void main(String[] args) {
        BlockingQueue<Object> blockingQueue = new LinkedBlockingQueue<Object>(10);
        new Thread(new Producer(blockingQueue)).start();
        new Thread(new Consumer(blockingQueue)).start();
    }
}

class Producer implements Runnable {
    private BlockingQueue<Object> blockingQueue;
    private Random random = new Random();

    public Producer(BlockingQueue<Object> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(2));
                blockingQueue.put(new Object());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {
    private BlockingQueue<Object> blockingQueue;
    private Random random = new Random();

    public Consumer(BlockingQueue<Object> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(4));
                blockingQueue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

2)锁

    public static void main(String[] args) {
        CustomBlockingQueue blockingQueue = new CustomBlockingQueue();
        new Thread(new Producer(blockingQueue)).start();
        new Thread(new Consumer(blockingQueue)).start();
    }
}

@SuppressWarnings("serial")
class CustomBlockingQueue extends LinkedList<Object> {
    private static final int MAX_SIZE = 10;

    private static final Lock lock = new ReentrantLock();
    private static final Condition fullState = lock.newCondition();
    private static final Condition emptyState = lock.newCondition();

    @Override
    public boolean offer(Object e) {
        boolean result;
        lock.lock();
        try {
            if (size() >= MAX_SIZE) {
                try {
                    fullState.await();
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
            result = super.offer(e);
            System.out.println("offer " + size());
            emptyState.signal();
        } finally {
            lock.unlock();
        }
        return result;
    }

    @Override
    public Object poll() {
        Object result;
        lock.lock();
        try {
            if (size() == 0) {
                try {
                    emptyState.await();
                } catch (InterruptedException e2) {
                    e2.printStackTrace();
                }
            }
            result = super.poll();
            System.out.println("poll  " + size());
            fullState.signal();
        } finally {
            lock.unlock();
        }
        return result;
    }
}

class Producer implements Runnable {
    private CustomBlockingQueue blockingQueue;
    private Random random = new Random();

    public Producer(CustomBlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(2));
                blockingQueue.offer(new Object());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {
    private CustomBlockingQueue blockingQueue;
    private Random random = new Random();

    public Consumer(CustomBlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(4));
                blockingQueue.poll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

3-4)显示器

    public static void main(String[] args) {
        CustomBlockingQueue blockingQueue = new CustomBlockingQueue();
        new Thread(new Producer(blockingQueue)).start();
        new Thread(new Consumer(blockingQueue)).start();
    }
}

@SuppressWarnings("serial")
class CustomBlockingQueue extends LinkedList<Object> {
    private static final int MAX_SIZE = 10;

    @Override
    public synchronized boolean offer(Object e) {
        if (size() >= MAX_SIZE) {
            try {
                wait();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
        boolean result = super.offer(e);
        System.out.println("offer " + size());
        notify();
        return result;
    }

    @Override
    public synchronized Object poll() {
        if (size() == 0) {
            try {
                wait();
            } catch (InterruptedException e2) {
                e2.printStackTrace();
            }
        }
        Object result = super.poll();
        System.out.println("poll  " + size());
        notify();
        return result;
    }
}

class Producer implements Runnable {
    private CustomBlockingQueue blockingQueue;
    private Random random = new Random();

    public Producer(CustomBlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(2));
                blockingQueue.offer(new Object());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {
    private CustomBlockingQueue blockingQueue;
    private Random random = new Random();

    public Consumer(CustomBlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(4));
                blockingQueue.poll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

    public static void main(String[] args) {
        CustomBlockingQueue blockingQueue = new CustomBlockingQueue();
        new Thread(new Producer(blockingQueue)).start();
        new Thread(new Consumer(blockingQueue)).start();
    }
}

@SuppressWarnings("serial")
class CustomBlockingQueue extends LinkedList<Object> {
    private static final int MAX_SIZE = 10;

    private static final Object fullLock = new Object();
    private static final Object emptyLock = new Object();

    @Override
    public boolean offer(Object e) {
        synchronized (fullLock) {
            if (size() >= MAX_SIZE) {
                try {
                    fullLock.wait();
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
        }
        synchronized (emptyLock) {
            boolean result = super.offer(e);
            System.out.println("offer " + size());
            emptyLock.notify();
            return result;
        }
    }

    @Override
    public Object poll() {
        synchronized (emptyLock) {
            if (size() == 0) {
                try {
                    emptyLock.wait();
                } catch (InterruptedException e2) {
                    e2.printStackTrace();
                }
            }
        }
        synchronized (fullLock) {
            Object result = super.poll();
            System.out.println("poll  " + size());
            fullLock.notify();
            return result;
        }
    }
}

class Producer implements Runnable {
    private CustomBlockingQueue blockingQueue;
    private Random random = new Random();

    public Producer(CustomBlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(2));
                blockingQueue.offer(new Object());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {
    private CustomBlockingQueue blockingQueue;
    private Random random = new Random();

    public Consumer(CustomBlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(4));
                blockingQueue.poll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

消费者生产者问题(也称为有界缓冲问题)是多进程同步问题的典型示例。该问题描述了两个进程,生产者和使用者,他们共享一个用作队列的通用固定大小缓冲区。制作人的工作是生成一段数据,将其放入缓冲区并重新开始。同时,消费者一次一件地消费数据(即,将其从缓冲器中移除)。问题是确保生产者不会尝试将数据添加到缓冲区中,如果它已满并且消费者不会尝试从空缓冲区中删除数据。

如果缓冲区已满,生产者的解决方案是进入睡眠状态或丢弃数据。消费者下次从缓冲区中删除项目时,它会通知生产者,生产者再次开始填充缓冲区。以同样的方式,如果消费者发现缓冲区为空,则消费者可以进入睡眠状态。下一次生产者将数据放入缓冲区时,它会唤醒沉睡的消费者。可以通过进程间通信来访问解决方案,通常使用信号量。解决方案不充分可能导致两个进程等待唤醒的死锁。这个问题也可以推广到拥有多个生产者和消费者。

0 个答案:

没有答案