java阻塞队列
对消息的处理有些麻烦,要保证各种确认。为了确保消息的100%发送成功,笔者在之前的基础上做了一些改进。其中要用到多线程,用于重复发送信息。
所以查了很多关于线程安全的东西,也看到了阻塞队列,发现这个模式很不错,可惜我目前用不到。
关于这个的讲解已经很多了,阻塞这个,就是当队列中没有数据的时候,线程读取的话会等待。当队列中的数据满的时候,线程添加数据的时候,也会等待。
有个例子很生动形象,往盘子里面放鸡蛋,只能放固定数目的。盘子里面没有鸡蛋,无法从中拿出来。当盘子里满了,也放不进去。直到被拿出去才能在放。
代码如下,这里设置的是一个盘子最多放10个鸡蛋:
package com.thread.two; import java.util.ArrayList;
import java.util.List; public class Plate {
List<Object> eggs=new ArrayList<Object>();public synchronized Object getEgg(){while(eggs.size()==0){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Object egg=null;
for (int i = 0; i < 10; i++) {
egg=eggs.get(i);
System.out.println("拿到鸡蛋.........");
}
//Object egg=eggs.get(0);
eggs.clear();
notify();
//System.out.println("拿到鸡蛋.........");
return egg;
} public synchronized void putEgg(Object egg){
while(eggs.size()>9){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
eggs.add(egg);
notify();
System.out.println("放入鸡蛋.........");
} static class AddThread extends Thread{
private Plate plate;
private Object egg=new Object();
public AddThread(Plate plate){
this.plate=plate;
}
public void run(){
for (int i = 0; i < 1000; i++) {
plate.putEgg(egg);
}
}
} static class GetThread extends Thread{
private Plate plate;
public GetThread(Plate plate){
this.plate=plate;
}
public void run(){
for (int i = 0; i < 1000; i++) {
plate.getEgg();
}
}
} public static void main(String[] args) throws InterruptedException {
Plate plate=new Plate();
Thread add=new Thread(new AddThread(plate));
Thread get=new Thread(new GetThread(plate));
add.start();
get.start();
add.join();
get.join();
System.out.println("测试结束");
} }
这个例子很形象,用线程实现了上面所说的。
java现在有concurrent包,里面有很多现成的可以用的类,很多是线程安全的,这样,像上面写的put或者get,都不需要自己写同步方法了,这些类已经包装好了。
这里有一个ArrayBlockingQueue的例子,和上面实现的差不多。
首先是两个线程,分别是put和get。
ThreadPut:
package com.thread.three; import java.util.concurrent.ArrayBlockingQueue; public class ThreadPut implements Runnable{
private ArrayBlockingQueue<String> abq=null;
public ThreadPut(ArrayBlockingQueue<String> abq){
this.abq=abq;
}
public void run() {
// TODO Auto-generated method stub
while(true){
System.out.println("要向队列中存数据了");
try {
Thread.sleep(1000);
abq.put("hi");
System.out.println("存入后,数据一共为:"+abq.size());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
ThreadGet:
package com.thread.three; import java.util.concurrent.ArrayBlockingQueue; public class ThreadGet extends Thread {
ArrayBlockingQueue<String> abq=null;
public ThreadGet(ArrayBlockingQueue<String> abq){
this.abq=abq;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("我要从队列中取数据了");
String msg=null;
if (abq.size()>0) {
msg=abq.remove();
}
System.out.println("队列中取得的数据为:"+msg+",队列中还有一共:"+abq.size());
}
}
}
测试类:
public class ArrayBlockQueueApp { public static void main(String[] args) {
ExecutorService es=Executors.newCachedThreadPool();
ArrayBlockingQueue<String> abq=new ArrayBlockingQueue<String>(10);
ThreadGet tGet=new ThreadGet(abq);
Thread tPut=new Thread(new ThreadPut(abq));
es.execute(tGet);
es.execute(tPut);
}
}
这些队列放消息的话挺不错的。
java阻塞队列的更多相关文章
- lesson2:java阻塞队列的demo及源码分析
本文向大家展示了java阻塞队列的使用场景.源码分析及特定场景下的使用方式.java的阻塞队列是jdk1.5之后在并发包中提供的一组队列,主要的使用场景是在需要使用生产者消费者模式时,用户不必再通过多 ...
- 细说并发5:Java 阻塞队列源码分析(下)
上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...
- Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例
Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...
- Java 并发系列之七:java 阻塞队列(7个)
1. 基本概念 2. 实现原理 3. ArrayBlockingQueue 4. LinkedBlockingQueue 5. LinkedBlockingDeque 6. PriorityBlock ...
- Java阻塞队列四组API介绍
Java阻塞队列四组API介绍 通过前面几篇文章的学习,我们已经知道了Java中的队列分为阻塞队列和非阻塞队列以及常用的七个阻塞队列.如下图: 本文来源:凯哥Java(kaigejava)讲解Java ...
- Java阻塞队列的实现
阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞.试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列 ...
- java阻塞队列与非阻塞队列
在并发编程中,有时候需要使用线程安全的队列.如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法. //使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入 ...
- (原创)JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别
阻塞队列:线程安全 按 FIFO(先进先出)排序元素.队列的头部 是在队列中时间最长的元素.队列的尾部 是在队列中时间最短的元素.新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素.链接 ...
- java阻塞队列之ArrayBlockingQueue
在Java的java.util.concurrent包中定义了和多线程并发相关的操作,有许多好用的工具类,今天就来看下阻塞队列.阻塞队列很好的解决了多线程中数据的安全传输问题,其中最典型的例子就是客园 ...
随机推荐
- android studio 中查找代码中的硬编码
在Android Studio中同时按下Ctrl + Shift+ F 或者其他自定义的快捷键,打开全局搜索,在全局搜索中输入 ^((?!(\*|//)).)+[\u4e00-\u9fa5] 并打勾 ...
- 【网络——Linux】——IPMI详细介绍【转】
一.IPMI含义 智能平台管理接口(IPMI:Intelligent Platform Management Interface)是一项应用于服务器管理系统设计的标准,由Intel.HP.Dell和N ...
- 网络存储-Samba、NAS---未知的用户名或错误密码
项目中的文件需要保存到网络存储设备中,之前用的是NAS.因没来得及采购就先用Samba顶上.代码发现通用…… 一.定义: Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器 ...
- WindowsCE project missing - 转
00x0 前言 之前在Windows 7系统中开发的WindowsCE项目,最近换成Windows 10系统,需要将项目进行修改,打开项目后提示如下错误: 无法读取项目文件“App.csproj”.. ...
- MTNET 自用ios网络库开源
短短两天就在https://git.oschina.net/gangwang/MTNET这里收获15个星 github 5星, 值得收藏! MTNET 自用ios网络库开源, 自用很久了,在数歀上架的 ...
- [Z]The Boost C++ Libraries
看起来是个学习boost非常不错的材料,应该是boost的官方教程之类: http://theboostcpplibraries.com/
- mycat配置日志
1: 1: MySql Host is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' ...
- tcp为什么需要3次握手4次挥手
一.起因 在网络请求中,为了提升性能,通常会采用长连接的方式避免在每一次交互都进行网络链接的创建和关闭,而长连接就是tpc的链接方式.因而有必要对tcp的创建链接和关闭有所了解.在网络上查询了一些知识 ...
- js apply/call/caller/callee/bind使用方法与区别分析
一.call 方法 调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容). Js代码 call([thisObj[,arg1[, arg2[, ...
- 【cs229-Lecture16】马尔可夫决策过程
之前讲了监督学习和无监督学习,今天主要讲“强化学习”. 马尔科夫决策过程:Markov Decision Process(MDP) 价值函数:value function 值迭代:value iter ...