java如何异步方式处理业务逻辑?

1.基础类-java.util.concurrent.ExcutorService

这个类的几个重要函数

shutdown 关闭任务池,无法传入新任务

shutdownnow 关闭所有任务,包括未执行完成的任务

submit 向任务池提交任务

2.基础接口-java.util.concurrent.Future

Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。

FutureTask 是实现了Future接口和Runnable接口,RunnableFuture接口

publicclassTest {

publicstaticvoidmain(String[] args) {

ExecutorService executor = Executors.newCachedThreadPool();

Task task =newTask();

Future<Integer> result = executor.submit(task);

executor.shutdown();

try{

Thread.sleep(1000);

}catch(InterruptedException e1) {

e1.printStackTrace();

}

System.out.println("主线程在执行任务");

try{

System.out.println("task运行结果"+result.get());

}catch(InterruptedException e) {

e.printStackTrace();

}catch(ExecutionException e) {

e.printStackTrace();

}

System.out.println("所有任务执行完毕");

}

}

classTaskimplementsCallable<Integer>{

@Override

publicInteger call()throwsException {

System.out.println("子线程在进行计算");

Thread.sleep(3000);

intsum =0;

for(inti=0;i<100;i++)

sum += i;

returnsum;

}

}

--------------------------------------------------------------------------

publicclassTest {

publicstaticvoidmain(String[] args) {

//第一种方式

ExecutorService executor = Executors.newCachedThreadPool();

Task task =newTask();

FutureTask<Integer> futureTask =newFutureTask<Integer>(task);

executor.submit(futureTask);

executor.shutdown();

//第二种方式,注意这种方式和第一种方式效果是类似的,只不过一个使用的是ExecutorService,一个使用的是Thread

/*Task task = new Task();

FutureTask<Integer> futureTask = new FutureTask<Integer>(task);

Thread thread = new Thread(futureTask);

thread.start();*/

try{

Thread.sleep(1000);

}catch(InterruptedException e1) {

e1.printStackTrace();

}

System.out.println("主线程在执行任务");

try{

System.out.println("task运行结果"+futureTask.get());

}catch(InterruptedException e) {

e.printStackTrace();

}catch(ExecutionException e) {

e.printStackTrace();

}

System.out.println("所有任务执行完毕");

}

}

classTaskimplementsCallable<Integer>{

@Override

publicInteger call()throwsException {

System.out.println("子线程在进行计算");

Thread.sleep(3000);

intsum =0;

for(inti=0;i<100;i++)

sum += i;

returnsum;

}

}

----------------------------------------------------------------------------------

3.StaticMethod.getResult方法的优化版本,异步方式

/**

* getResult 的优化版本 异步,非阻塞方式

* @author jwjw233233@163.com

* @param url 接口地址

* @param param 接口参数

*/

public static void getResult_Asynchronous(final String url, final String param) {

ExecutorService es = Executors.newCachedThreadPool();

es.submit(new Callable<String>() {

@Override

public String call() throws Exception {

PrintWriter out = null;

BufferedReader in = null;

String result = "";

try {

URL realUrl = new URL(url);

// 打开和URL之间的连接

URLConnection conn = realUrl.openConnection();

// 设置通用的请求属性

conn.setRequestProperty("accept", "*/*");

conn.setRequestProperty("connection", "Keep-Alive");

conn.setRequestProperty("user-agent",

"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");

// 发送POST请求必须设置如下两行

conn.setDoOutput(true);

conn.setDoInput(true);

// 获取URLConnection对象对应的输出流

out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));

// 发送请求参数

out.print(param);

// flush输出流的缓冲

out.flush();

// 定义BufferedReader输入流来读取URL的响应

in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

String line;

while ((line = in.readLine()) != null) {

result += line;

}

} catch (Exception e) {

System.out.println("发送POST请求出现异常!" + e);

System.out.println("url=" + url + "?" + param);

}

// 使用finally块来关闭输出流、输入流

finally {

try {

if (out != null) {

out.close();

}

if (in != null) {

in.close();

}

} catch (IOException ex) {

}

}

return result;

}

});

es.shutdown();

}

----------------------------------------------------------------------------

测试函数

public static void main(String[] args) {

System.out.println(new Date());

StaticMethod.getResult_Asynchronous("http://cs.jiwu.com/build!home.action?b, "");

System.out.println(new Date());

System.out.println(new Date());

StaticMethod.getResult("http://cs.jiwu.com/build!home.action?b, "");

System.out.println(new Date());

}

输出结果:

Fri Apr 15 14:41:22 CST 2016

Fri Apr 15 14:41:22 CST 2016

Fri Apr 15 14:41:22 CST 2016

Fri Apr 15 14:41:32 CST 2016

---------------------------------------------------------------------------------------------------------

结论:采用异步方式更新一个楼盘页 几乎不需要等待,而采用同步方式却花费了10s的时间,性能有巨大差距!