java生产者消费者专题---谈谈wait与sleep

生产者消费者是个经典的话题了,这次主要通过这个话题谈谈wait方法与sleep方法。

wait方法和sleep方法都是让出cpu占有权,让其它线程能够得到运行,不同的地方在于wait方法可以通过notify或者notifyAll方法主动唤醒或者wait一定的等待时间自动恢复运行,而sleep方法只能在等待一定的时间后自动恢复运行。

一般我们看到的生产者消费者实现都是通过wait、notify、notifyAll或者是condition接口的await、signal、signalAll方法实现的。这次我们想看看通过sleep方法实现与wait方法实现的效率有多大差别。

wait方式实现:

package pro_con;

import java.util.LinkedList;

public class QueueWithWait<T> extends BlockingQueue<T> {
    private LinkedList<T> queue = new LinkedList<>();
    private final int cacheSize;

    public QueueWithWait(int cacheSize) {
        super();
        this.cacheSize = cacheSize;
    }

    public T take() {
        synchronized (queue) {
            while(true) {
                if(queue.size()>0) {
                    T obj = queue.poll();
                    queue.notify();
                    return obj;
                }else {
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        }
    }

    public void put(T obj) {

        synchronized (queue) {
            while (true) {
                if (queue.size() < cacheSize) {
                    queue.offer(obj);
                    queue.notify();
                    break;
                } else {
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                    }
                }

            }
        }

    }

}
 

 

sleep方式实现:

package pro_con;

import java.util.LinkedList;

public class QueueWithSleep<T> extends BlockingQueue<T> {

    private LinkedList<T> queue = new LinkedList<>();
    private final int cacheSize;

    public QueueWithSleep(int cacheSize) {
        super();
        this.cacheSize = cacheSize;
    }

    public T take() {
        while (true) {
            synchronized (queue) {
                if (queue.size() > 0) {
                    T obj = queue.poll();
                    return obj;
                } else {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                    }
                }
            }
        }
    }

    public void put(T obj) {
        while (true) {
            synchronized (queue) {
                if (queue.size() < cacheSize) {
                    queue.offer(obj);
                    break;
                } else {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                    }
                }

            }
        }

    }

}

测试结果:

wait方式的前7次结果如下图所示

6e42bc5074fa3c7bd2208eba5dbdc109d92.jpg

sleep方式的前7次结果如下图所示

e67321438775b4bda4c4204353e846ba67f.jpg

结果是很明显的,wait方式比sleep方式效率要高出很多,可能会简单的认为sleep的时间过长导致的,那么把sleep方法去掉后结果如下:

6758576b4c2b51aa5301b37bc0def96029e.jpg

结果发现效率与wait方式差不多,但是仔细观察会发现这种去掉sleep的方法结果是不稳定的,不像wait方法稳定在290万左右,原因是

去掉sleep方法后同一个put或者take方法在达到临界条件时有一定几率会多次循环,不像wait方法主动让出cpu占用权,从而降低了程序

的效率。

结论:

主流的生产者消费者模式还是用wait或者condition接口的await方式,但还有一种无锁队列会比这更加高效。

 

代码下载链接:https://pan.baidu.com/s/1ciLBNiIc9670cwdat2qspQ 密码:z5d1

 

 

转载于:https://my.oschina.net/u/1268334/blog/1922842

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值