对消息的处理有些麻烦,要保证各种确认。为了确保消息的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. [原创]实现android知乎、一览等的开场动画图片放大效果

    代码下载地址: https://github.com/Carbs0126/AutoZoomInImageView 知乎等app的开场动画为:一张图片被显示到屏幕的正中央,并充满整个屏幕,过一小段时间后 ...

  2. 详细介绍windows下使用python pylot进行网站压力测试

    windows下使用python进行网站压力测试,有两个必不可少的程序需要安装,一个是python,另一个是pylot.python是一个安装软件,用来运行python程序,而pylot则是pytho ...

  3. MariaDB Galera Cluster 10.1 只支持 LINUX ?!

    MariaDB Galera Cluster  (MariaDB 10.1) 当前只支持:LINUX ! 参考: https://mariadb.com/kb/en/mariadb/getting-s ...

  4. Mac OSX 安装nvm(node.js版本管理器)

    我的系统 1.打开github官网https://github.com/,输入nvm搜索,选择creationix/nvm,打开 2.找到Install script,复制 curl -o- http ...

  5. 跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByClassName

    按照类名获取元素 -- getElementsByClassName(HTML5) 标准 WHATWG 在Document与Element上均有定义,原型 HTMLCollection getElem ...

  6. c和c++关于const的一些区别

    以下参考了网上的一些资料并通过程序验证. 注意,以下情况都是用gcc和g++编译器得到的结果,用vs编译器又会有所不同. 以下说下c和c++中const定义的常量的一些区别: c++中用const定义 ...

  7. storm分组模式

    Shuffle grouping: Tuples被随机分配到每一个bolt’s task,以便于每一个bolt’s task获得相同数量的tuples. Fields grouping: Stream ...

  8. fzu 2107 Hua Rong Dao(状态压缩)

    Problem 2107 Hua Rong Dao Accept: 106    Submit: 197 Time Limit: 1000 mSec    Memory Limit : 32768 K ...

  9. java中三种方式获得类的字节码文件对象

    package get_class_method; public class ReflectDemo { /** * @param args */ public static void main(St ...

  10. codeforces C. Design Tutorial: Make It Nondeterministic

    题意:每一个人 都有frist name 和 last name! 从每一个人的名字中任意选择 first name 或者 last name 作为这个人的编号!通过对编号的排序,得到每一个人 最终顺 ...