java阻塞队列实现 生产者消费者 模型

硅谷探秘者 1585 0 0

        在生产中我们可能会遇到在处理正常业务的过程中,其中会夹杂着一些非必需或不是特别重要的业务,而且这些业务还比较耗时,这个时候为了不影响正常业务性能,我们可以这些不是特别重要而且还比较耗时的业务独立出来,放入后台的一个执行队列中,后台可以慢慢执行,当队列中没有业务数据时,使该执行线程进入等待状态。当业务数据添加进队列中后唤醒处于等待状态的执行线程,继续处理业务。

一、阻塞队列的实现

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);
	}
}

 


评论区
请写下您的评论...
暂无评论...
猜你喜欢
java基础 1508 java线程通讯之式是并发、多线程编程中经典的设计式,通过分离的执行工作解耦,简化了开发式,可以以不同的速度数据。一个
java基础 4408 变为非空。2.的应用场景:常用于的场景,是向里添加元素的线程,是从里取元素的线程。简而言之,用来存放元素、获取元素的容器。3
official 1231 上一篇《(mq)rabbitmq安装延时插件延时息1》文章中介绍了rabbitmq安装延时插件。本编将继续结合代码来延时(基于springboot项目)。下方所有源代码均已上传
official 1290 上一篇文章《(mq)rabbitmq息发送确认》介绍了息发布时的确认方案,本篇文章将介绍,确认的方法。和确认发布一样,有时也需要确认,rabbitmq有三种确认
official 1190 一、什么是bio?bio即:同步式IO。就是传统的javaio网络。javabio有两个的地方,第一个地方是需要的监听端口,等待客户端链接。第二个需要Socket的read方法
official 1285 来的问题,那么netty就对解决这个问题提供了多线程的解决方案。netty的线程际上Netty线程就是Reactor式的一个,而Reactor式又是什么呢?Reactor式是基于事件
java基础 1779 基于双向链表结构直接代码:packagethreadTest.test6;publicclassNodeE{ privateEe; privateNodeEprve; privateNodeEnext; publicNode(Ee){ super(); this.e=e; } publicEgetE(){ returne; } publicvoidsetE(Ee){ this.e=e; }
official 1378 之前的文章中提到了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 加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。