在生产中我们可能会遇到在处理正常业务的过程中,其中会夹杂着一些非必需或不是特别重要的业务,而且这些业务还比较耗时,这个时候为了不影响正常业务性能,我们可以这些不是特别重要而且还比较耗时的业务独立出来,放入后台的一个执行队列中,后台可以慢慢执行,当队列中没有业务数据时,使该执行线程进入等待状态。当业务数据添加进队列中后唤醒处于等待状态的执行线程,继续处理业务。
一、阻塞队列的实现
package com.dzqc.uniauth.config;
/**
* 链式阻塞队列
* @author 硅谷探秘者(jia)
* @param <E>
*/
public class LinkedBlockingQueue<E> {
class Node{
public E e;
public Node next;
public Node prev;
public Node(E e) {
super();
this.e = e;
}
}
//队首
private Node head=null;
//队尾
private Node tail=null;
//队列长度
private volatile int size=0;
//入队
public synchronized void push(E e) {
Node n=new Node(e);
if(size==0) {
head=tail=n;
}else {
n.prev=tail;
tail.next=n;
tail=n;
}
size++;
//唤醒业务线程执行业务
this.notify();
}
//出队
public synchronized E pop() {
Node n=null;
if(size==1) {
n=head;
head=tail=null;
size--;
}else if(size>1){
n=head;
head=head.next;
n.next=head.prev=null;
size--;
}
return n==null?null:n.e;
}
//当前线程休眠
public synchronized void waits() {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
二、并发下的业务场景模拟测试
package com.dzqc.uniauth.config;
import java.util.concurrent.atomic.AtomicInteger;
class Art{
public int a;
public Art(int a){
this.a=a;
}
}
public class Test {
static AtomicInteger p=new AtomicInteger(0);
static AtomicInteger q=new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
LinkedBlockingQueue<Art> l=new LinkedBlockingQueue<Art>();
/**
* 处理业务的线程
*/
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
Art a=l.pop();
if(a!=null) {
System.out.println("处理业务:"+a.a);
try {
//模拟耗时
Thread.sleep(3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
//休眠
l.waits();
}
}
}
}).start();
/**
* 产生业务的线程
*/
Thread ts[]=new Thread[3000];
for(int i=0;i<3000;i++) {
ts[i]=new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
l.push(new Art(p.addAndGet(1)));
q.addAndGet(1);
}
});
ts[i].start();
}
for(Thread t:ts) {
t.join();
}
Thread.sleep(10000);
/**
* 产生业务的线程
*/
Thread ts2[]=new Thread[3000];
for(int i=0;i<3000;i++) {
ts2[i]=new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
l.push(new Art(p.addAndGet(1)));
q.addAndGet(1);
}
});
ts2[i].start();
}
for(Thread t:ts2) {
t.join();
}
System.out.println("--"+q);
}
}