基于java中BlockingQueue的使用介绍_java

      最近在维护一个java工程,在群里面也就聊起来java的优劣!无奈一些Java的终极粉丝,总是号称性能已经不必C++差,并且很多标准类库都是大师级的人写的,如何如何稳定等等。索性就认真研究一番,他们给我的一项说明就是,在线程之间投递消息,用java已经封装好的BlockingQueue,就足够用了。

      既然足够用那就写代码测试喽,简简单单写一个小程序做了一番测试:

复制代码 代码如下:

//默认包
import java.util.concurrent.*;

import base.MyRunnable;

public class Test
{
    public static void main(String[] args)
    {
        BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
        java.lang.Runnable r = new MyRunnable(queue);
        Thread t = new Thread(r);
        t.start();

        while(true)
        {
            try
            {
                while(true)
                {
                    for(int i =0;i < 10000;i++)
                    {
                        queue.offer(i);
                    }
                }
            }
            catch ( Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}

 
//需要添加的包
package base;

import java.lang.Runnable;
import java.util.concurrent.*;
import java.util.*;

public class MyRunnable implements Runnable
{
    public MyRunnable(BlockingQueue<Integer> queue)
    {
        this.queue = queue;
    }
    public void run()
    {
        Date d = new Date();
        long starttime = d.getTime();
        System.err.println(starttime);
        int count = 0;
        while(true)
        {
            try
            {
                Integer i = this.queue.poll();
                if(i != null)
                {
                    count ++;
                }
                if(count == 100000)
                {
                    Date e = new Date();
                    long endtime = e.getTime();
                    System.err.println(count);
                    System.err.println(endtime);
                    System.err.print(endtime - starttime);
                    break;
                }

            }
            catch (Exception e)
            {

            }
        }
    }
    private BlockingQueue<Integer> queue;
}

         传递十万条数据,在我的测试机上面,大概需要50ms左右,倒是还可以!索性就看了一下BlockingQueue的底层实现

 我在上面的测试代码中使用的offer 和 poll,就看看这两个实现函数吧,首先是offer

复制代码 代码如下:

public E poll() {
        final AtomicInteger count = this.count;
        if (count.get() == 0)
            return null;
        E x = null;
        int c = -1;
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lock();
        try {
            if (count.get() > 0) {
                x = extract();
                c = count.getAndDecrement();
                if (c > 1)
                    notEmpty.signal();
            }
        } finally {
            takeLock.unlock();
        }
        if (c == capacity)
            signalNotFull();
        return x;
    }

      和一般的同步线程类似,只是多加了一个signal,在学习unix环境高级编程时候,看到条件变量用于线程之间的同步,可以实现线程以竞争的方式实现同步!
poll函数的实现也是类似!

复制代码 代码如下:

public boolean offer(E e) {
        if (e == null) throw new NullPointerException();
        final AtomicInteger count = this.count;
        if (count.get() == capacity)
            return false;
        int c = -1;
        final ReentrantLock putLock = this.putLock;
        putLock.lock();
        try {
            if (count.get() < capacity) {
                insert(e);
                c = count.getAndIncrement();
                if (c + 1 < capacity)
                    notFull.signal();
            }
        } finally {
            putLock.unlock();
        }
        if (c == 0)
            signalNotEmpty();
        return c >= 0;
    }

时间: 2024-09-28 05:01:06

基于java中BlockingQueue的使用介绍_java的相关文章

java中定义常量方法介绍_java

java没有叫全局变量的东西(有全局变量还叫OO吗?):原因:Java将所有设计都基于对象的基础上.Java的全局变量只能对一个类内部而言.能够在类内的任何地方使用的变量就是全局变量,而只在某个特定的函数或者局部的程序块内使用的变量则是局部变量. 所以:声明为static的变量实质上就是全局变量.当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量. 使用:java中只有static和非static变量,这个属于每个类的,如果需要全局变量比如PI(3

基于java中反射的总结分析_java

刚开始学习java的时候真的很难理解反射到底是个什么东西 一些书籍,哪怕是很经典的书籍都解释的让人感觉懵懵的,或许的确是我太笨 况且,网上说在将来学习框架的时候需要经常应用到反射机制,这样一来总让人心里有些不安 就方才偶然又把讲解反射的章节和视频看了一点,觉得能理解一些了 现在决定一鼓作气,边看边写,顺便把一些主要的内容和操作都记载到这里 我想,对于我这么一个笨笨的人来说,学习的最好方法也许就是不断重复 遇到不懂的知识就停下来把以往的重新学一遍,虽然浪费了很多时间,但对我也有些效果   我的理解

Java中的transient关键字介绍_java

transient说明一个属性是临时的,不会被序列化. 下面是一个Demo,name声明为 transient,不被序列化 package com.zzs.tet; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.

基于java中泛型的总结分析_java

要我直接说出泛型是个what我还真讲不出来,这里先由一道问题引入: 定义一个坐标点类,要求能保存各种类型的数据,如:整形,浮点型,和字符串类型 既然变量类型起先不确定,那么很容易想到就是用所有类型的父类,也就是Object类来代替 不废话了,用代码来体现 实例1:用Object来实现不确定的数据类型输入 复制代码 代码如下: //这是定义的坐标点类class Point {    private Object x;    private Object y;     //用Object来表示不确定

基于Java中Math类的常用函数总结_java

Java中比较常用的几个数学公式的总结: //取整,返回小于目标函数的最大整数,如下将会返回-2 Math.floor(-1.8): //取整,返回发育目标数的最小整数 Math.ceil() //四舍五入取整 Math.round() //计算平方根 Math.sqrt() //计算立方根 Math.cbrt() //返回欧拉数e的n次幂 Math.exp(3); //计算乘方,下面是计算3的2次方 Math.pow(3,2); //计算自然对数 Math.log(); //计算绝对值 Mat

基于java中byte数组与int类型的转换(两种方法)_java

java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法,我们都知道,在socket传输中,发送.者接收的数据都是 byte数组,但是int类型是4个byte组成的,如何把一个整形int转换成byte数组,同时如何把一个长度为4的byte数组转换为int类型.下面有两种方式. public static byte[] int2byte(int res) { byte[] targets = new byte[4]; targets[0] = (byte) (res & 0xf

基于Java中字符串内存位置详解_java

前言 之前写过一篇关于JVM内存区域划分的文章,但是昨天接到蚂蚁金服的面试,问到JVM相关的内容,解释一下JVM的内存区域划分,这部分答得还不错,但是后来又问了Java里面String存放的位置,之前只记得String是一个不变的量,应该是要存放在常量池里面的,但是后来问到new一个String出来应该是放到哪里的,这个应该是放到堆里面的,后来又问到String的引用是放在什么地方的,当时傻逼的说也是放在堆里面的,现在总结一下:基本类型的变量数据和对象的引用都是放在栈里面的,对象本身放在堆里面,

基于java中stack与heap的区别,java中的垃圾回收机制的相关介绍_java

#. 在java中有两类内存.分别称为stack(堆栈)和heap(堆). stack是程序内存空间,因此所有的基本类型和对象的引用是存在stack中. heap是java虚拟机储存对象的,它是一个巨大的内存,当你创造一个对象,java虚拟机把对象放入heap中,把创造的对象的地址放入stack中. 因此,基本类型.对象的引用储存在stack中:对象储存在heap中. #. java中的垃圾回收机制 当你new一个新的对象,java分配必需的内存.当你用完一个对象时,java的垃圾回收器为你把内

基于java中正则操作的方法总结_java

正则表达式在处理字符串的效率上是相当高的 关于正则表达式的使用,更多的是自己的经验,有兴趣可以参阅相关书籍 这里主要写一下java中的正则操作方法 实例1:匹配 复制代码 代码如下: import java.util.Scanner; class Demo {    public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        //获取输入        System.out