Java 异步处理简单实践
http://www.cnblogs.com/fangfan/p/4047932.html
同步与异步
通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异步则意味着某个处理过程可以允许多个线程同时处理。
异步通常代表着更好的性能,因为它很大程度上依赖于缓冲,是典型的使用空间换时间的做法,例如在计算机当中,高速缓存作为cpu和磁盘io之间的缓冲地带协调cpu高速计算能力和磁盘的低速读写能力。
volatile
应用场景:检查一个应用执行关闭或中断状态。因为此关键字拒绝了虚拟对一个变量多次赋值时的优化从而保证了虚拟机一定会检查被该关键字修饰的变量的状态变化。
CountDownLatch
应用场景:控制在一组线程操作执行完成之前当前线程一直处于等待。例如在主线程中执行await()方法阻塞主线程,在工作线程执行完逻辑后执行countDown()方法。
本文示例场景:
1,从控制台发送消息到消息服务器(由一个队列模拟)。
2,将消息队列写入到文件(对写文件的操作设置延时以模拟性能瓶颈)。
3,消息服务器作为控制台和文件写入之间的缓冲区。
示例代码:
注:往消息队列添加消息可以通过for循环一次性加入,本文为了便于观察文件和队列的变化而采用了控制台输入,实际写一行文件记录速度应该高于手速,所以本文示例中增加了线程sleep时间。
package org.wit.ff.ch2; import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; /**
*
* <pre>
* 简单异步处理示例.
* </pre>
*
* @author F.Fang
* @version $Id: AsyncHandler.java, v 0.1 2014年10月23日 下午11:37:54 F.Fang Exp $
*/
public class AsyncHandler { /**
* 控制资源释放.
*/
private CountDownLatch latch; /**
* 处理完成标识.
*/
private volatile boolean handleFinish; /**
* 消息写入本地文件完成.
*/
private volatile boolean sendFinish; /**
* 阻塞队列.
*/
private BlockingQueue<String> queue; private BufferedWriter bw; public AsyncHandler(CountDownLatch latch) {
this.latch = latch;
/**
* 使用链表实现.
*/
queue = new LinkedBlockingQueue<String>();
File file = new File("E:/hello.txt");
try {
bw = new BufferedWriter(new FileWriter(file));
} catch (IOException e) {
throw new RuntimeException(e);
}
} public void handle() {
// 模拟性能瓶颈的执行过程,3s处理一条消息.
new Thread() {
public void run() {
while (!handleFinish) {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e1) {
// 不做处理.
}
String s = queue.peek();
if (s != null) {
queue.poll();
try {
bw.write(s);
bw.newLine();
} catch (IOException e) {
}
}
// 若队列为空并且消息发送完成.
if (queue.isEmpty() && sendFinish) {
// 计数器1->0
latch.countDown();
// 让处理过程结束.
handleFinish = true;
break;
}
}
} }.start(); } /**
*
* <pre>
* 给出消息发送完成的标识.
* </pre>
*
*/
public void sendFinish() {
sendFinish = true;
} /**
*
* <pre>
* 资源释放.
* </pre>
*
*/
public void release() {
System.out.println("release!");
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
// TODO 打印日志.
}
}
//其实使用queue = null就够了.
if (queue != null) {
queue.clear();
queue = null;
}
} /**
*
* <pre>
* 往队列发送消息.
* </pre>
*
* @param text
*/
public void sendMsg(String text) {
if (text != null && !text.isEmpty()) {
queue.add(text);
}
} public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(1);
AsyncHandler handler = new AsyncHandler(latch);
handler.handle(); // 做一次检查.
Scanner scanner = new Scanner(System.in);
while (true) {
String text = scanner.next();
// 若用户选择退出.
if ("exit".equals(text)) {
// 表示消息已经发送完成.
handler.sendFinish();
break;
}
handler.sendMsg(text);
} try {
// 阻塞主线程等待消息写入到本地文件完成.
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 释放资源 文件流,队列.
handler.release();
// 关闭控制台输入.
scanner.close();
} }
Java 异步处理简单实践的更多相关文章
- 【转】Java 异步处理简单实践
同步与异步 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异步则意味着某个处理过程可以允许多个线程同时处理. 异步通常代表着更好的性能,因为它很大程度上依赖于缓冲,是典型的使用空间 ...
- java fork/join简单实践
我们知道,java8中有并行流,而并行流在后台的实现是通过fork/join池来完成的,例如: List<Integer> a = buildList(); List<Integer ...
- 使用DataStax Java驱动程序的最佳实践
引言 如果您想开始建立自己的基于Cassandra的Java程序,欢迎! 也许您已经参加过我们精彩的DataStax Academy课程或开发者大会,又或者仔细阅读过Cassandra Java驱动的 ...
- Thrift简单实践
0.什么是RPC RPC(Remote Procedure Call - 远程过程调用),是通过网络从远程计算机上请求服务,而不需要了解底层网路技术的细节.简单点说,就是像调用本地服务(方法)一样调用 ...
- Paip.Php Java 异步编程。推模型与拉模型。响应式(Reactive)”编程FutureData总结... 1
Paip.Php Java 异步编程.推模型与拉模型.响应式(Reactive)"编程FutureData总结... 1.1.1 异步调用的实现以及角色(:调用者 提货单) F ...
- 【JAVA零基础入门系列】Day12 Java类的简单应用
俗话说的好,实践出真知,所以除了理论知识掌握扎实以外,更重要的是要多加操练,这样才能掌握核心科技. 今天我们就用刚学会的类来实践一下,目标便是完成上一篇中的剁手任务. 我们的商品类已经准备好了,代码重 ...
- kafka原理和实践(二)spring-kafka简单实践
系列目录 kafka原理和实践(一)原理:10分钟入门 kafka原理和实践(二)spring-kafka简单实践 kafka原理和实践(三)spring-kafka生产者源码 kafka原理和实践( ...
- Java操作符真的简单到易如反掌?
之前我写了一篇<吃人的那些Java名词:对象.引用.堆.栈和堆栈>,本以为凭借自己8年的Java编程经验足够把这些“吃人”的Java名词解释清楚了,但有网友不以为然,在文章底部评论说:“老 ...
- [Java并发编程(四)] Java volatile 的理论实践
[Java并发编程(四)] Java volatile 的理论实践 摘要 Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 ...
随机推荐
- 作用域链–JS基础核心之一
JS中的作用域,大家都知道的,分为全局作用域和局部作用域,没有块级作用域,听起来其实很简单的,可是作用域是否能够有深入的了解,对于JS代码逻辑的编写成功率,BUG的解决能力,以及是否能写出更优秀的代码 ...
- 如何编写android ANE
1.编写AndroidAne.jar: a.编写SkyContext.java: import java.util.HashMap;import java.util.Map;import com.ad ...
- spring随手笔记1:constructor-arg
<bean id="Hello" class="com.ltf.captha.serviceImpl.HelloWorldServiceImpl"> ...
- linux 查看剩余内存数
返回的是kb的数值 cat /proc/meminfo | grep MemFree | cut -d ":" -f2 | sed -e 's/\(^ *\)//' -e 's/\ ...
- Java:Collection List Set
Java:集合 常见集合:List Set List 特点:元素是有序的,而且元素可以重复,因为该集合体系有索引. 常见的三个子类:ArrayList.LinkedList.Verctor List集 ...
- windows下python安装pyquery
安装pyquery之前首先要明确一点,easyinstall 是一款python包管理器,类似于node的npm,用于安装python的扩展包,它安装的包是以*.egg的方式. 要安装pq需要经历以下 ...
- 【个人使用.Net类库】(3)Excel文件操作类(基于NPOI)
Web开发工作中经常要根据业务的需要生成对应的报表.经常采用的方法如下: 将DataTable导出至Excel文件; 读取模板Excel文件; 修改模板Excel文件对应的内容. 因此,便想到封装一个 ...
- Linux shell的&&和||
Linux shell的&&和|| shell 在执行某个命令的时候,会返回一个返回值,该返回值保存在 shell 变量 $? 中.当 $? == 0 时,表示执行成功:当 $? ...
- Service中事务不能回滚的解决方式(转)
1.在service方法里面如果对异常进行了捕获的话,该事务是不会进行回滚的 默认spring事务只在发生未被捕获的 runtimeexcetpion时才回滚. spr ...
- ios网络学习------6 json格式数据的请求处理
ios网络学习------6 json格式数据的请求处理 分类: IOS2014-06-30 20:33 471人阅读 评论(3) 收藏 举报 #import "MainViewContro ...