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包中定义了和多线程并发相关的操作,有许多好用的工具类,今天就来看下阻塞队列.阻塞队列很好的解决了多线程中数据的安全传输问题,其中最典型的例子就是客园 ...
随机推荐
- 支持取消操作和暂停操作的Backgroundworker
这也是今天讨论的话题.取消是默认就支持的,而暂停则默认不支持.但通过ManualResetEvent可以对其进行干预. using System; using System.Collections.G ...
- android 电量分析工具
.参考文章:https://developer.android.com/studio/profile/battery-historian.html 这篇文章讲的是如果dump 电量日子文件batter ...
- LESS详解之函数(四)
之前已经为大家介绍了一些LESS函数,大家应该对之前介绍的有所了解了.下面依旧为大家介绍LESS的函数,附加着一些小例子.希望这些有关LESS的函数能在大家编写LESS的时候有所帮助. saturat ...
- 15.6.8-sql小技巧
取月头月尾: declare @someDay datetime,@firstDay datetime,@endDay datetime set @someDay='2015.2.2' ,) ,) s ...
- duilib 的IE浏览器控件去边框和去滚动条的代码
近些天在duilib群里经常有朋友问起,怎么让duilib的IE控件可以去边框,去滚动条的问题,或者是如何去控件IE控件的行为.为了避免重复的回答,我就写一篇博文,把处理方法说明一下. duilib中 ...
- WPF常用控件样式集锦
1.不规则形状按钮(通过更改path实现) <Style x:Key="ButtonStyleForPath" TargetType="{x:Type Button ...
- 关于fork的一道经典面试题
这是一道面试题,问程序最终输出几个“-”: #include<stdio.h> #include<sys/types.h> #include<unistd.h> i ...
- 使用GROUP BY统计记录条数 COUNT(*) DISTINCT
例如这样一个表,我想统计email和passwords都不相同的记录的条数 CREATE TABLE IF NOT EXISTS `test_users` ( `email_id` ) unsigne ...
- MSSQL大数据量增加字段耗时对比
单个数据表记录数为1亿4千万条. 一.测试同时增加两个允许为空的字段. ALTER TABLE [dbo].[XRecord] ADD [sType] int,[cType] int GO 开始时间: ...
- 为什么移动Web应用程序很慢(译)
前些日子,看到Herb Sutter在自己的博客中推荐了一篇文章<Why mobile web apps are slow>,在推荐里他这样写道: “I don’t often link ...