`
headof
  • 浏览: 23024 次
  • 来自: ...
社区版块
存档分类
最新评论

about FutureTask

 
阅读更多
FutureTask
仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。
建立个callable。返回一个string
	static class nCallable implements Callable<String> {

		@Override
		public String call() throws Exception {
			System.out.println("now,this callable is calculating...");
			return "some object";
		}
		
	}

建立一个main函数。
	public static void main(String[] args) {
		
		FutureTask<String> ft = new FutureTask<String>(new nCallable());
		
		System.out.println("future task start up.");
		ft.run();
		try {
			System.out.println(ft.get());
			System.out.println(ft.get());
			System.out.println(ft.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		System.out.println("future task run finished.");
		
	}


利用FutureTask这个特性。当对某个对象只进行一次初始化的情况下。这个特性就有用了。
例如访问一个cache,cache只能进行一次初始化,如果有两个线程并发进行初始化这个cache的情况下,如果不加控制,那么很可能cache会被初始化两次。现在使用FutureTask可以避免这个问题。
	public V initialize(Object id, Callable<V> callable) throws Exception {
		//
		FutureTask<V> task = tasks.get(id);
		if(task == null) {
			task = new FutureTask<V>(callable);
			FutureTask<V> existing = tasks.putIfAbsent(id, task);
			if(existing == null) {
				task.run();
			} else {
				task = existing;
			}
		}
		
		//
		try {
			return task.get();
		} catch (InterruptedException e) {
			Thread.currentThread().interrupt();
			return null;
		} catch (ExecutionException e) {
			if(e.getCause() instanceof Error) {
				throw (Error)e.getCause();
			} else {
				throw (Exception)e.getCause();
			} 
		} finally {

		}
	}


两个线程并发访问到initialize方法
TimeThread1Thread2
A tasks.get(id)==null
B tasks.get(id)==null
C new FutureTask new FutureTask
D tasks.putIfAbsent tasks.putIfAbsent only one will put success.
E if put scuess
E  tasks.putIfAbsent <> null
F task.run() task = existing
G task.get() task.get() same result
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics