java 多线程并发设计模式之一: Future 模式应用

摘要: JDK1.5 之后对并发设计做了很大的改动,最明显的一点是是提供了:java.util.concurrent 这个包,里面包含了很多新的多线程开发的API, 用起来很方便也很实用, 今天先测试 用Future 模式来设计多线程. 所谓Future 模式,发出请求之后,在未收到请求之前,程序可以继续向下执行. 这样程序就不必等待请求的返回。因此这里是并行执行的.

JDK1.5 之后对并发设计做了很大的改动,最明显的一点是是提供了:java.util.concurrent 这个包,里面包含了很多新的多线程开发的API, 用起来很方便也很实用, 今天先测试 用Future 模式来设计多线程. 所谓Future 模式,发出请求之后,在未收到请求之前,程序可以继续向下执行. 这样程序就不必等待请求的返回。因此这里是并行执行的.

我们经常网购,在网上买东西之后,并不会坐在家等东西送上门,如果按照电脑思维,你得不吃不喝,就在哪里傻等,但事实上,会这样吗?你再买东西之后,你还可以继续做其他的事情,比如去拍拖, 几天之后,客户准备好货并在快递公司的时候,你直接自己去取货或者在家收货就好了。这就是Futrue 模式的简单比喻. 用程序来实现它类似如下:
1. 你先在网上订一件东西。
2. 你再另外一个网上又订了一件东西
3. 自己去做一些其他的事情。
4. 看看东西到了没有,去收货。

package com.yihaomen.future;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
    	//构造FutureTask
        FutureTask buy = new FutureTask(new RealData("a"));
        ExecutorService executor = Executors.newFixedThreadPool(2);
        //执行FutureTask
        //在这里开启线程进行RealData的call()执行
        executor.submit(buy);
        /*还可以直接这么用,与上面不同的是没有具体的Callable 的是实现类,直接定义匿名类实现,*/
        Callable buy2 = new Callable() {			
			public Object call() throws Exception {				
				Thread.sleep(100);
				System.out.println("第二个 执行完毕");
				return "future2";
			}
		};
		executor.submit(buy2);		
        System.out.println("请求完毕");
        try {
        //这里依然可以做额外的数据操作,这里使用sleep代替其他业务逻辑的处理
        	System.out.println("开始主线程");
            Thread.sleep(2000);
            System.out.println("主线程执行完毕");
        } catch (InterruptedException e) {
        }
        
        //取得call()方法的返回值
        //如果此时call()方法没有执行完成,则依然会等待        
        System.out.println("future= " + buy.get());
		executor.shutdown();
    }
}


用到一个辅助类:
package com.yihaomen.future;

import java.util.concurrent.Callable;

public class RealData implements Callable {
    private String para;
    public RealData(String para){
    	this.para=para;
    }
	@Override
	public String call() throws Exception {
    	
    	StringBuffer sb=new StringBuffer();
        for (int i = 0; i < 10; i++) {
        	sb.append(para);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("买东西 执行完毕");
        return sb.toString();
	}
}


由此可见: Future 模式主要是利用了 Callable 接口。FutureTask 实现了Runable 接口, 然后去调用Callable 接口的 call 方法返回结果,其实future 除了 call 方法之外,还有 取消任务,设置超时时间等很强大的功能。

个人觉得 Futue 的强大功能,就在于省去了主函数中的等待时间,用等待的时间去做其他的事情,从而实现并发,但其他执行的事件的结果最好不能在主程序中使用,否则还是得等待,一般来说互不干扰的几个事件,采用这种方法很好

源代码下载:
java multiple thread future pattern sample

上一篇: java执行命令行或者shell脚本,批处理的基本方法
下一篇: java 多线程并发设计模式之二: Master worker 模式应用

Avatar

放学不走 评论于: 2015-01-21

您好,方便提问个问题:
多线程的初始化有Thread thread = new Thread(Runnable target);这么个方法,
假如:
Class Account implements Runnable(){
  public void run(){
   }
}
main 方法:
Account a1 = new Account();Account a2 = new Account();
Thread t1 = new Thread(a1); Thread t2 = new Thread(a1);
-----------------------------------------------------------------------
Thread tt1 = new Thread(a1);Thread tt2= new Thread(a2);
问下横线上下两部分这个初始化方式区别在哪里?尤其是使用锁的时候,有点晕。望楼主指点迷津,小弟不胜感激。
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号