对消息的处理有些麻烦,要保证各种确认。为了确保消息的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阻塞队列的更多相关文章

  1. lesson2:java阻塞队列的demo及源码分析

    本文向大家展示了java阻塞队列的使用场景.源码分析及特定场景下的使用方式.java的阻塞队列是jdk1.5之后在并发包中提供的一组队列,主要的使用场景是在需要使用生产者消费者模式时,用户不必再通过多 ...

  2. 细说并发5:Java 阻塞队列源码分析(下)

    上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...

  3. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

  4. Java 并发系列之七:java 阻塞队列(7个)

    1. 基本概念 2. 实现原理 3. ArrayBlockingQueue 4. LinkedBlockingQueue 5. LinkedBlockingDeque 6. PriorityBlock ...

  5. Java阻塞队列四组API介绍

    Java阻塞队列四组API介绍 通过前面几篇文章的学习,我们已经知道了Java中的队列分为阻塞队列和非阻塞队列以及常用的七个阻塞队列.如下图: 本文来源:凯哥Java(kaigejava)讲解Java ...

  6. Java阻塞队列的实现

    阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞.试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列 ...

  7. java阻塞队列与非阻塞队列

    在并发编程中,有时候需要使用线程安全的队列.如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法. //使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入 ...

  8. (原创)JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别

    阻塞队列:线程安全 按 FIFO(先进先出)排序元素.队列的头部 是在队列中时间最长的元素.队列的尾部 是在队列中时间最短的元素.新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素.链接 ...

  9. java阻塞队列之ArrayBlockingQueue

    在Java的java.util.concurrent包中定义了和多线程并发相关的操作,有许多好用的工具类,今天就来看下阻塞队列.阻塞队列很好的解决了多线程中数据的安全传输问题,其中最典型的例子就是客园 ...

随机推荐

  1. XSHELL配色方案及导入配色方案的方法

    [ubuntu] text(bold)=ffffff magenta(bold)=ad7fa8 text=ffffff white(bold)=eeeeec green=4e9a06 red(bold ...

  2. config中自定义配置

    1. 定义自己的KeyValue <section name="TestKeyValue" type="System.Configuration.NameValue ...

  3. Hibernate缓存原理与策略 Hibernate缓存原理:

    Hibernate缓存原理: 对于Hibernate这类ORM而言,缓存显的尤为重要,它是持久层性能提升的关键.简单来讲Hibernate就是对JDBC进行封装,以实现内部状态的管理,OR关系的映射等 ...

  4. python + hadoop (案例)

    python如何链接hadoop,并且使用hadoop的资源,这篇文章介绍了一个简单的案例! 一.python的map/reduce代码 首先认为大家已经对haoop已经有了很多的了解,那么需要建立m ...

  5. PlayFramework 1.2.x 在Controller 中识别JSON提交

    链接 http://stackoverflow.com/questions/6132892/consuming-json-in-play-framework-controller @Global pu ...

  6. android xml解析添加到listview中的问题

    一个问题不知什么原因,代码: public class OtherActivity extends ListActivity { @Override protected void onCreate(B ...

  7. linq join多字段

    from VS in m2db.Inf_VehicleSale join RS1 in m2db.His_RecSale on new { VS.vehicleCode, auctionCode=VS ...

  8. 重新发现梯度下降法--backtracking line search

    一直以为梯度下降很简单的,结果最近发现我写的一个梯度下降特别慢,后来终于找到原因:step size的选择很关键,有一种叫backtracking line search的梯度下降法就非常高效,该算法 ...

  9. GDC2014免费slide整理下载

    GDC2014图形和程序相关的部分免费slide整理下载:)http://pan.baidu.com/s/1eQzMrxo gdc14_An Indie Approach to procedural ...

  10. 使用UIKit制作卡牌游戏(二)ios游戏篇

    转自朋友Tommy 的翻译,自己只翻译了第三篇教程. 译者: Tommy | 原文作者: Matthijs Hollemans写于2012/07/06 原文地址: http://www.raywend ...