jdk1.5——阻塞队列应用案例

标签: jdk1 队列 应用 | 发表时间:2014-10-23 17:39 | 作者:chengjianxiaoxue
出处:http://www.iteye.com
 

 

1 打印日志: 原来打印16个日志需要16秒时间,现在开启4个线程,让这16个任务在4秒内完成:

 

思路:    
    0创建容量16的队列   
    1 将16个任务增加到 阻塞队列中      
    2开启4个线程,每次从队列中获取数据   
       
    这样主线程不停的放, 并发来的4个线程不停的取, 你可以理解为并发一次来了4个线程,每个线程取到后内部打印1S操作仍旧不变,   
    执行4次,一共耗时4S完成原来16秒不用并发下的操作   
       
    主线程放log 和 子线程取log 之间用condtion notEmpty notFull 来实现阻塞   
  
  
public class Test {   
       
    public static void main(String[] args){   
        // 0 创建容量只为1的队列   
        final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(16);   
        // 2 开启4个线程,每次从队列中获取数据   
        for(int i=0;i<4;i++){   
            new Thread(new Runnable(){   
                @Override  
                public void run() {   
                    while(true){   
                        try {   
                            String log = queue.take();   
                            parseLog(log);   
                        } catch (InterruptedException e) {   
                            e.printStackTrace();   
                        }   
                    }   
                }   
                   
            }).start();   
        }   
           
        // 1 将16个任务在主线程中增加到阻塞队列中   
        System.out.println("begin:"+(System.currentTimeMillis()/1000));   
        for(int i=0;i<16;i++){  //这行代码不能改动   
            final String log = ""+(i+1);//这行代码不能改动   
            {   
                    try {   
                        queue.put(log);   
                    } catch (InterruptedException e) {   
                        // TODO Auto-generated catch block   
                        e.printStackTrace();   
                    }   
                    //Test.parseLog(log);   
            }   
        }   
    }   
       
    //parseLog方法内部的代码不能改动   
    public static void parseLog(String log){   
        System.out.println(log+":"+(System.currentTimeMillis()/1000));   
           
        try {   
            Thread.sleep(1000);   
        } catch (InterruptedException e) {   
            e.printStackTrace();   
        }          
    }   
       
}  

 

 

2 数据有序一个个输出

 

package queue;

import java.util.concurrent.Semaphore;
import java.util.concurrent.SynchronousQueue;

/**
 * 设计10个线程来消费 数据,要求达到 每次消费的数据是有序,并且是一个个的输出
 * 
 * 设计点:
 * 要求是 1 顺序输出  2 每次输出一个
 * 1 守门员semaphore设置每次进来只有1个
 * 2 使用阻塞队列SynchronousQueue,其特点就是只有在取数据线程来的时候,入数据线程才将数据放进去,类似于Exchanger作用,达到顺序输出效果
 * @author zm
 *
 */
public class Test {

	public static void main(String[] args) {
		// 一个计数信号量。信号量维护了一个许可集,即每次进入的个数, 这里设置为每次只能进1个
		final Semaphore semaphore = new Semaphore(1);
		final SynchronousQueue<String> queue = new SynchronousQueue<String>();
		for(int i=0;i<10;i++){// 开启10个消费线程
			new Thread(new Runnable(){ 
				@Override
				public void run() {	
					try {
						semaphore.acquire(); // 每次线程进来 都c从问守门员semaphore那获得申请
						String input = queue.take();
						String output = TestDo.doSome(input);
						System.out.println(Thread.currentThread().getName()+ ":" + output);
						semaphore.release();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}	
				}
			}).start();
		}
		
		System.out.println("begin:"+(System.currentTimeMillis()/1000));
		for(int i=0;i<10;i++){  //这行不能改动
			String input = i+"";  //这行不能改动
			try {
				queue.put(input);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

//不能改动此TestDo类
class TestDo {
	public static String doSome(String input){
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		String output = input + ":"+ (System.currentTimeMillis() / 1000);
		return output;
	}
}

 

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [jdk1 队列 应用] 推荐:

jdk1.5——阻塞队列应用案例

- - 行业应用 - ITeye博客
1 打印日志: 原来打印16个日志需要16秒时间,现在开启4个线程,让这16个任务在4秒内完成:. 1 将16个任务增加到 阻塞队列中. 2开启4个线程,每次从队列中获取数据. 这样主线程不停的放, 并发来的4个线程不停的取, 你可以理解为并发一次来了4个线程,每个线程取到后内部打印1S操作仍旧不变,.

用消息队列和消息应用状态表来消除分布式事务

- Wolf - 淘宝核心系统团队博客
由于数据量的巨大,大部分Web应用都需要部署很多个数据库实例. 这样,有些用户操作就可能需要去修改多个数据库实例中的数据. 传统的解决方法是使用分布式事务保证数据的全局一致性,经典的方法是使用两阶段提交协议. 长期以来,分布式事务提供的优雅的全局ACID保证麻醉了应用开发者的心灵,很多人都不敢越雷池一步,想像没有分布式事务的世界会是怎样.

RabbitMQ:镜像队列Mirrored queue

- - 飞翔的荷兰人
        在上一节 《RabbitMQ集群类型一:在单节点上构建built-in内置集群》中我们已经学习过:在集群环境中,队列只有元数据会在集群的所有节点同步,但队列中的数据只会存在于一个节点,数据没有冗余且容易丢,甚至在durable的情况下,如果所在的服务器节点宕机,就要等待节点恢复才能继续提供消息服务.

快速的消息队列 SquirrelMQ

- Le - 开源中国社区最新软件
SquirrelMQ是一个快速的消息队列.   SquirrelMQ VS Redis 入队列: SquirrelMQ:100万条数据,105S,内存使用84MB. Redis:100万条数据,156S,内存使用127MB.   出队列:   SquirrelMQ:100万条数据,230S. Redis:100万条数据,163S.

队列并不能解决“超载”

- - 博客园_新闻
人们总是错误地使用队列,最坏的情况是用它解决“超载(overload)”问题. Fred Hebert 是《 Learn You Some Erlang for Great Good!》一书的作者. 在这本 Erlang 入门书籍中,他结合生动的插图、恰当的实例以浅显易懂的方式讲解了技术问题. 近日,他以同样的方式 阐释了为什么“队列不能解决超载”.

Hadoop层级队列组织方式

- - 董的博客
Dong | 新浪微博: 西成懂 | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及 版权声明. 网址: http://dongxicheng.org/mapreduce/hadoop-hierarchy-queues/. 在Hadoop 0.20.x版本或者更早的版本,Hadoop采用了平级队列组织方式,在这种组织方式中,管理员可将用户分到若干个扁平队列中,在每个队列中,可指定一个或几个队列管理员管理这些用户,比如杀死任意用户的作业,修改任意用户作业的优先级.

Feed消息队列架构分析

- - Tim[后端技术]
最近一两年,大部分系统的数据流由基于日志的离线处理方式转变成实时的流式处理方式,并逐渐形成几种通用的使用方式,以下介绍微博的消息队列体系. 当前的主要消息队列分成如图3部分. 1、feed信息流主流程处理,图中中间的流程,通过相关MQ worker将数据写入cache、Redis及MySQL,以便用户浏览信息流.

redis作为消息队列的使用

- - ITeye博客
在redis支持的数据结构中,有一个是集合list. 对List的操作常见的有lpush  lrange等. 在这种常见的操作时,我们是把集合当做典型意义上的‘集合’来使用的. 往往容易被忽视的是List作为“队列”的使用情况. 反编译redis的jar包,会发现:.  pop意为“弹”,是队列里的取出元素.

高可用消息队列框架ZBUS

- - 企业架构 - ITeye博客
我们在日常开发中可以需要用到消息队列 当然我们完全可以自己写一个生产者-消费者框架 但是高可用性、实时性已经大量数据堆积时候就显得问题捉襟见肘了下面推荐的框架在我时间项目中和测试中都是非常不错那么他是什么框架呢.    zbus git地址. http://git.oschina.net/rushmore/zbus ZBUS=MQ+RPC 服务总线 1)支持消息队列, 发布订阅, RPC, 交易系统队列适配 2)亿级消息堆积能力、支持HA高可用 3)无依赖单个Jar包 ~300K 4)丰富的API--JAVA/C/C++/C#/Python/Node.JS多语言接入,支持HTTP等协议长连接入.

[转]消息队列的两种模式

- -
Java消息服务(Java Message Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信. 点对点与发布订阅最初是由JMS定义的. 这两种模式主要区别或解决的问题就是发送到队列的消息能否重复消费(多订阅).