Java 异步处理简单实践
Java 异步处理简单实践
同步与异步
通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异步则意味着某个处理过程可以允许多个线程同时处理。
异步通常代表着更好的性能,因为它很大程度上依赖于缓冲,是典型的使用空间换时间的做法,例如在计算机当中,高速缓存作为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();
}
}
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Elasticsearch 数据搜索
ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API。本篇就通过一些简单的搜索命令,帮助你理解ES的相关应用。虽然不能让你理解ES的原理设计,但是可以帮助你理解ES,探寻更多的特性。 搜索API ES提供了两种搜索的方式:请求参数方式 和 请求体方式。 - 请求参数方式 curl'localhost:9200/bank/_search?q=*&pretty' 其中bank是查询的索引名称,q后面跟着搜索的条件:q=*表示查询所有的内容 - 请求体方式(推荐这种方式) curl-XPOST'localhost:9200/bank/_search?pretty'-d' { "query":{"match_all":{}} }' 这种方式会把查询的内容放入body中,会造成一定的开销,但是易于理解。在平时的练习中,推荐这种方式。 返回的内容: { "took":26, "timed_out":false, "_shards":{ "total":5, "successful":5, "failed":0 }, "hits":{ "total":1000, "m...
- 下一篇
Spring Cloud(四)服务提供者 Eureka + 服务消费者 Feign
上一篇文章,讲述了如何通过RestTemplate + Ribbon去消费服务,这篇文章主要讲述如何通过Feign去消费服务。 Feign简介 Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。 使用Feign,只需要创建一个接口并注解,它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解,Feign支持可插拔的编码器和解码器,Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。 Feign 具有如下特性: 可插拔的注解支持,包括Feign注解和JAX-RS注解 支持可插拔的HTTP编码器和解码器 支持Hystrix和它的Fallback 支持Ribbon的负载均衡 支持HTTP请求和响应的压缩Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。它整合了Ribbon和Hystrix,从而不再需要显式地使用这两个组件。Feign还提供了HTTP请求的模板,通过编写简单的接口和注解,就可以定义好HTTP请求的参数、格式、地址等信息。接下来,Feign会完全代理HTTP的请...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题