基于java中BlockingQueue的使用介紹
更新時(shí)間:2013年04月19日 14:20:24 作者:
本篇文章小編為大家介紹,基于java中BlockingQueue的使用介紹。需要的朋友參考下
最近在維護(hù)一個(gè)java工程,在群里面也就聊起來java的優(yōu)劣!無奈一些Java的終極粉絲,總是號稱性能已經(jīng)不必C++差,并且很多標(biāo)準(zhǔn)類庫都是大師級的人寫的,如何如何穩(wěn)定等等。索性就認(rèn)真研究一番,他們給我的一項(xiàng)說明就是,在線程之間投遞消息,用java已經(jīng)封裝好的BlockingQueue,就足夠用了。
既然足夠用那就寫代碼測試嘍,簡簡單單寫一個(gè)小程序做了一番測試:
//默認(rèn)包
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;
}
傳遞十萬條數(shù)據(jù),在我的測試機(jī)上面,大概需要50ms左右,倒是還可以!索性就看了一下BlockingQueue的底層實(shí)現(xiàn)
我在上面的測試代碼中使用的offer 和 poll,就看看這兩個(gè)實(shí)現(xiàn)函數(shù)吧,首先是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;
}
和一般的同步線程類似,只是多加了一個(gè)signal,在學(xué)習(xí)unix環(huán)境高級編程時(shí)候,看到條件變量用于線程之間的同步,可以實(shí)現(xiàn)線程以競爭的方式實(shí)現(xiàn)同步!
poll函數(shù)的實(shí)現(xiàn)也是類似!
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;
}
既然足夠用那就寫代碼測試嘍,簡簡單單寫一個(gè)小程序做了一番測試:
復(fù)制代碼 代碼如下:
//默認(rèn)包
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;
}
傳遞十萬條數(shù)據(jù),在我的測試機(jī)上面,大概需要50ms左右,倒是還可以!索性就看了一下BlockingQueue的底層實(shí)現(xiàn)
我在上面的測試代碼中使用的offer 和 poll,就看看這兩個(gè)實(shí)現(xiàn)函數(shù)吧,首先是offer
復(fù)制代碼 代碼如下:
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;
}
和一般的同步線程類似,只是多加了一個(gè)signal,在學(xué)習(xí)unix環(huán)境高級編程時(shí)候,看到條件變量用于線程之間的同步,可以實(shí)現(xiàn)線程以競爭的方式實(shí)現(xiàn)同步!
poll函數(shù)的實(shí)現(xiàn)也是類似!
復(fù)制代碼 代碼如下:
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;
}
相關(guān)文章
Java泛型在集合使用與自定義及繼承上的體現(xiàn)和通配符的使用
泛型又稱參數(shù)化類型,是Jdk5.0 出現(xiàn)的新特性,解決數(shù)據(jù)類型的安全性問題,在類聲明或?qū)嵗瘯r(shí)只要指定好需要的具體的類型即可。Java泛型可以保證如果程序在編譯時(shí)沒有發(fā)出警告,運(yùn)行時(shí)就不會產(chǎn)生ClassCastException異常。同時(shí),代碼更加簡潔、健壯2021-09-09Java實(shí)現(xiàn)一個(gè)簡單的緩存方法
本篇文章主要介紹了Java實(shí)現(xiàn)一個(gè)簡單的緩存方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04詳解SpringMVC的url-pattern配置及原理剖析
這篇文章主要介紹了SpringMVC的url-pattern配置及原理剖析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Springboot使用JustAuth實(shí)現(xiàn)各種第三方登陸
本文主要介紹了Springboot使用JustAuth實(shí)現(xiàn)各種第三方登陸,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Java Swing JSlider滑塊的實(shí)現(xiàn)示例
這篇文章主要介紹了Java Swing JSlider滑塊的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12java實(shí)現(xiàn)往hive 的map類型字段寫數(shù)據(jù)
這篇文章主要介紹了java實(shí)現(xiàn)往hive 的map類型字段寫數(shù)據(jù)操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Java實(shí)現(xiàn)動態(tài)獲取文件的絕對路徑
我們知道在?Java?中讀取一些配置文件信息,是在開發(fā)中十分常用的要求。這篇文章就來和大家聊聊Java如何實(shí)現(xiàn)動態(tài)獲取文件的絕對路徑,感興趣的可以了解一下2023-02-02