java阻塞队列实现 生产者消费者 模型
在生产中我们可能会遇到在处理正常业务的过程中,其中会夹杂着一些非必需或不是特别重要的业务,而且这些业务还比较耗时,这个时候为了不影响正常业务性能,我们可以这些不是特别重要而且还比较耗时的业务独立出来,放入后台的一个执行队列中,后台可以慢慢执行,当队列中没有业务数据时,使该执行线程进入等待状态。当业务数据添加进队列中后唤醒处于等待状态的执行线程,继续处理业务。
一、阻塞队列的实现
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);
}
}
评论区
请写下您的评论...
猜你喜欢
blog
java线程通讯之生产者消费者模式
java基础
1516
java线程通讯之生产者消费者模式生产者消费者模式是并发、多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据。一个生产和消
blog
阻塞队列及其原理
java基础
4413
待队列变为非空。2.阻塞队列的应用场景:阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加元素的线程,消费者是从队列里取元素的线程。简而言之,阻塞队列是生产者用来存放元素、消费者获取元素的容器。3
official
1244
上一篇《(mq)rabbitmq安装延时队列插件实现延时消息1》文章中介绍了rabbitmq安装延时队列插件。本编将继续结合代码来实现延时队列(基于springboot项目)。下方所有源代码均已上传
official
1303
上一篇文章《(mq)rabbitmq消息发送确认》介绍了消息发布时的确认方案,本篇文章将介绍,消息消费确认的方法。和确认发布一样,消费者有时也需要确认,rabbitmq有三种确认模式
official
1198
一、什么是bio?bio即:同步阻塞式IO。就是传统的javaio网络模型。javabio有两个阻塞的地方,第一个地方是需要阻塞的监听端口,等待客户端链接。第二个需要阻塞Socket的read方法
official
1297
来的问题,那么netty就对解决这个问题提供了多线程的解决方案。netty的线程模型实际上Netty线程模型就是Reactor模式的一个实现,而Reactor模式又是什么呢?Reactor模式是基于事件
blog
非阻塞队列的实现
java基础
1784
基于双向链表结构直接代码:packagethreadTest.test6;publicclassNodeE{ privateEe; privateNodeEprve; privateNodeEnext; publicNode(Ee){ super(); this.e=e; } publicEgetE(){ returne; } publicvoidsetE(Ee){ this.e=e; }
official
1391
之前的文章中提到了java中的nio是同步非阻塞的网络io模型,本文就主要说明一下同步、异步、阻塞、非阻塞的概念来帮助理解nio。io操作IO分两阶段(一旦拿到数据后就变成了数据操作,不再是IO
最新发表
归档
2018-11
12
2018-12
33
2019-01
28
2019-02
28
2019-03
32
2019-04
27
2019-05
33
2019-06
6
2019-07
12
2019-08
12
2019-09
21
2019-10
8
2019-11
15
2019-12
25
2020-01
9
2020-02
5
2020-03
16
2020-04
4
2020-06
1
2020-07
7
2020-08
13
2020-09
9
2020-10
5
2020-12
3
2021-01
1
2021-02
5
2021-03
7
2021-04
4
2021-05
4
2021-06
1
2021-07
7
2021-08
2
2021-09
8
2021-10
9
2021-11
16
2021-12
14
2022-01
7
2022-05
1
2022-08
3
2022-09
2
2022-10
2
2022-12
5
2023-01
3
2023-02
1
2023-03
4
2023-04
2
2023-06
3
2023-07
4
2023-08
1
2023-10
1
2024-02
1
2024-03
1
2024-04
1
2024-08
1
标签
算法基础
linux
前端
c++
数据结构
框架
数据库
计算机基础
储备知识
java基础
ASM
其他
深入理解java虚拟机
nginx
git
消息中间件
搜索
maven
redis
docker
dubbo
vue
导入导出
软件使用
idea插件
协议
无聊的知识
jenkins
springboot
mqtt协议
keepalived
minio
mysql
ensp
网络基础
xxl-job
rabbitmq
haproxy
srs
音视频
webrtc
javascript
加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。