Java并发(九)生产者·消费者实现

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41594698/article/details/100037824

1.synchronized实现

队列

static class MyBlockingQueue<E> {
    private Queue<E> queue = null;
    private int limit;

    public MyBlockingQueue(int limit) {
        this.limit = limit;
        queue = new ArrayDeque<>(limit);
    }

    public synchronized void put(E e) throws InterruptedException {
        while (queue.size() == limit) {
            wait();
        }
        queue.add(e);
        notifyAll();
    }

    public synchronized E take() throws InterruptedException {
        while (queue.isEmpty()) {
            wait();
        }
        E e = queue.poll();
        notifyAll();
        return e;
    }
}

生产者:

static class Producer extends Thread {
    MyBlockingQueue<String> queue;

    public Producer(MyBlockingQueue<String> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        int num = 0;
        try {
            while (true) {
                String task = String.valueOf(num);
                queue.put(task);
                System.out.println("produce task " + task);
                num++;
                Thread.sleep((int) (Math.random() * 100));
            }
        } catch (InterruptedException e) {
        }
    }
}

消费者:

static class Consumer extends Thread {
    MyBlockingQueue<String> queue;

    public Consumer(MyBlockingQueue<String> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                String task = queue.take();
                System.out.println("handle task " + task);
                Thread.sleep((int)(Math.random()*100));
            }
        } catch (InterruptedException e) {
        }
    }
}

main:

public static void main(String[] args) {
    MyBlockingQueue<String> queue = new MyBlockingQueue<>(10);
    new Producer(queue).start();
    new Consumer(queue).start();
}

2.显示锁实现

队列

static class MyBlockingQueue<E> {
    private Queue<E> queue = null;
    private int limit;
    private Lock lock = new ReentrantLock();
    private Condition notFull  = lock.newCondition();
    private Condition notEmpty = lock.newCondition();


    public MyBlockingQueue(int limit) {
        this.limit = limit;
        queue = new ArrayDeque<>(limit);
    }

    public void put(E e) throws InterruptedException {
        lock.lockInterruptibly();
        try{
            while (queue.size() == limit) {
                notFull.await();
            }
            queue.add(e);
            notEmpty.signal();    
        }finally{
            lock.unlock();
        }
    }

    public E take() throws InterruptedException {
        lock.lockInterruptibly();
        try{
            while (queue.isEmpty()) {
                notEmpty.await();
            }
            E e = queue.poll();
            notFull.signal();
            return e;    
        }finally{
            lock.unlock();
        }
    }
}

3.线程池

直接将任务丢给线程池,需要结果的话就get即可

生产者把任务丢给线程池,线程池创建线程并处理任务;
如果需要运行的任务数大于线程池的核心线程数,就把任务扔到阻塞队列里。

这种做法比只使用一个阻塞队列来实现生产者和消费者模式显然要高明很多,因为消费者能够处理直接就处理掉了(execute方法里就有“创建线程并执行”的步骤),这样速度更快,而生产者先存,消费者再取这种方式显然慢一些。

展开阅读全文

java实现生产者-消费者

03-01

class Message rn private String title; rn private String content; rn private boolean flag = true;rnrn public synchronized void set(String title, String content) rn if (flag == false) rn try rn super.wait();rn catch (InterruptedException e) rn // TODO 自动生成的 catch 块rn e.printStackTrace();rn rn rn [color=#FF0000]else[/color]rn this.title = title;rn this.content = content;rn this.flag = false;rn super.notify();rn rnrn public synchronized void get() rn if (flag == true) rn try rn super.wait();rn catch (InterruptedException e) rn // TODO 自动生成的 catch 块rn e.printStackTrace();rn rn rn [color=#FF0000]else[/color]rn System.out.println(this.title + "---->" + this.content);rn this.flag = true;rn super.notify();rn rnrnrnclass Producer implements Runnable // 定义生产者rn private Message mes = null;rnrn public Producer(Message mes) rn this.mes = mes;rn rnrn public void run() rn for (int i = 0; i < 20; i++) rn if (i % 2 == 0) rn this.mes.set("**", "学习java");rn else rn this.mes.set("**", "学习C++");rn rn rn rnrnrnclass Consumer implements Runnable // 定义消费者rn private Message com = null;rnrn public Consumer(Message com) rn this.com = com;rn rnrn public void run() rn for (int i = 0; i < 20; i++) rn this.com.get();rn rn rnrnrnpublic class ProducerConsumer rn public static void main(String[] args) throws Exception rn Message msg = new Message(); // 定义Message对象,用于保存和取出数据rn new Thread(new Producer(msg)).start(); // 启动生产者线程rn new Thread(new Consumer(msg)).start(); // 取得消费者线程rn rnrn为什么加了这else就不行啊?去掉任意一个或全去掉就行啊,rn谢谢啦。 论坛

生产者消费者问题(JAVA实现

08-10

[code=java]public class TestProducerConsumerrn public static void main(String[] agrs)rn SyncStack ss = new SyncStack();rn Producer p = new Producer(ss);rn ConSumer c = new ConSumer(ss);rn new Thread(p).start();rn new Thread(c).start();rnrn rnrnrnclass Wotornrn int id;rn public Woto(int id)rn this.id = id;rn rnrn public String toString()rn return "Woto:" + id;rn rnrnclass SyncStackrn int index = 0;rn Woto[] w = new Woto[8];rnrn public synchronized void push(Woto wt)rn while(index == w.length)rn try rn this.wait();rn catch (InterruptedException e) rnrn e.printStackTrace();rn rn rn this.notify();rn w[index] = wt;rn index++;rn rnrn public synchronized Woto pop()rn while(index == 0)rn try rn this.wait();rn catch (InterruptedException e) rn e.printStackTrace();rn rn rn this.notify();rn index--;rn return w[index];rn rnrnrnclass Producer implements Runnablern SyncStack ss = null;rn public Producer(SyncStack ss)rn this.ss = ss;rn rnrn public void run() rn for(int i = 0;i<10;i++)rn Woto wt = new Woto(i);rn ss.push(wt);rn System.out.println("生产了="+wt);rn try rn Thread.sleep((int) (Math.random() * 200));rn catch (InterruptedException e) rnrn e.printStackTrace();rn rn rn rnrnrnclass ConSumer implements Runnablern SyncStack ss = null;rn public ConSumer(SyncStack ss)rn this.ss = ss;rn rnrn public void run() rn for(int i = 0;i<10;i++)rnrn Woto wt =ss.pop();rn System.out.println("消费了="+wt);rn try rn Thread.sleep((int) (Math.random() * 1000));rn catch (InterruptedException e) rn e.printStackTrace();rn rnrn rn rn[/code]rnrn为什么会先出现消费者呢 ?求大神解答rnrn[img=https://img-bbs.csdn.net/upload/201508/10/1439200218_273169.png][/img]rnrn求解决办法 论坛

没有更多推荐了,返回首页