`
liushulin
  • 浏览: 1590 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

FutureTask实现缓存Demo

阅读更多
package com.samples.thread;

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class Test_CacheByFuture {

	/**
	 *  
	 */
	public static void main(String[] args) {
		Test_CacheByFuture tc = new Test_CacheByFuture();
		tc.start();
	}
	
	
	/**
	 * 测试 用FutureTask、ConcurrentMap实现的缓存示例
	 */
	public void start(){
		final CacheManager cache = new CacheManager();
		ExecutorService es = Executors.newFixedThreadPool(100);
		for(int i=1;i<=50;i++){
			final int key = (int) (Math.random()*10);
			es.execute(new Runnable() {
				
				@Override
				public void run() {
					try {
						Thread.sleep((long) (Math.random()*100));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					String result = cache.get(String.valueOf(key));
					System.out.println(Thread.currentThread().getName()+"  获取完成。。。 结果:"+result);
				}
			});
		}
		
	}
	
	
	class CacheManager {
		//适用于并发的hashMap
		ConcurrentHashMap<String,FutureTask<String>> concurrentHashMap = new ConcurrentHashMap<String,FutureTask<String>>();
		
		public String get(String key){
			String result = "default";
			//ConcurrentHashMap本身就是支持并发操作的 所以读写的时候不需要加锁,内部实现已经加锁处理。
			FutureTask<String> task = concurrentHashMap.get(key);
			if(task==null){
				FutureTask<String> tempTask = new FutureTask<String>(new Callable<String>() {
					@Override
					public String call() throws Exception {
						Thread.sleep(3*1000);
						return "complete "+new Date().toLocaleString();
					}
				});
				/**
				 * putIfAbsent:
				 * 如果没有这个key,那么放入key-value,返回null。
				 * 如果有这个key,那么返回value。
				 * 整个操作时原子性的,因为内部实现加锁了。
				 */
				/**
				 * 缓存的意义在于:一定要确保map中保存的task已经执行完成,通过get方法直接可以取出计算好的结果来。如果单纯的就是
				 * put进去一个没有执行的task,没有任何意义。所以使用putIfAbsent,第一次放进task之后去执行这个task,以后就不执行了。
				 */
				task = concurrentHashMap.putIfAbsent(key, tempTask);
				if(task==null){
					task = tempTask;
					System.out.println("key="+key+" 开始计算........");
					task.run();
				}
			}
			
			try {
				System.out.println("开始去key="+key+" 的结果");
				result = task.get();
			} catch (InterruptedException e) {
				e.printStackTrace();
				//如果get被中断,那么直接取消任务
				task.cancel(true);
				//此时暂时用不上,但是还是写上吧
				//Thread.currentThread().interrupt();
				concurrentHashMap.remove(key);
			} catch (ExecutionException e) {
				e.printStackTrace();
				concurrentHashMap.remove(key);
			} catch(Exception e){
				e.printStackTrace();
				concurrentHashMap.remove(key);
			}
			
			return result;
			
		}
		
	}
	

}

 

分享到:
评论

相关推荐

    借助Ehcache缓存框架实现对页面的缓存Demo

    本工程用于研究如何借助Ehcache缓存框架实现对页面的缓存 本工程编码方式:UTF-8 本工程开发工具:MyEclipse 说明: 1、ehcache.xml和ehcache.xsd两个文件可以在下在下载下来的名为“ehcache-core-x.x.x-...

    Java线程池FutureTask实现原理详解

    Java线程池FutureTask实现原理详解 Java线程池FutureTask实现原理详解是Java多线程编程中的一种重要机制,用于追踪和控制线程池中的任务执行。下面将详细介绍FutureTask的实现原理。 类视图 为了更好地理解...

    futuretask用法及使用场景介绍

    FutureTask的实现机制是通过传入Runnable或者Callable的任务给FutureTask,然后调用其run方法或通过线程池执行,最后可以在外部通过FutureTask的get方法异步获取执行结果。 FutureTask还可以确保即使调用了多次run...

    简谈java并发FutureTask的实现

    在这个简谈中,我们将深入探讨`FutureTask`的实现原理和使用方式。 首先,`FutureTask`实现了`Runnable`接口,这意味着它可以直接被`Executor`服务执行。同时,它也实现了`Future`接口,提供了检查任务是否完成、...

    FutureTask底层实现分析,有了FutureTask主线程要想获得工作线程(异步计算线程)的结果变得比较简单

    FutureTask 底层实现分析 FutureTask 是 Java 中的一种非常重要的多线程设计模式,用于异步计算线程之间的结果传递。在 JDK 中,FutureTask 类是 Future 模式的实现,它实现了 Runnable 接口,作为单独的线程运行。...

    FutureTask学习

    `FutureTask`是Java并发编程中的一个重要组件,它位于`java.util.concurrent`包下,是`Executor`框架的一部分。...在实际开发中,你可以根据需求选择适合的线程池,结合`FutureTask`实现复杂并发场景的解决方案。

    spring线程池ThreadPoolExecutor配置以及FutureTask的使用

    `FutureTask`是`java.util.concurrent`包中的一个类,它实现了`Future`接口,允许我们执行一个任务并获取其结果。当我们提交一个`FutureTask`到线程池时,可以异步地执行任务,并在需要时获取结果。下面是一个使用`...

    比较java中Future与FutureTask之间的关系

    2.FutureTask可以接收Callable的实现类,也可以接收Runnable的实现类。 3. 使用Future时,需要实现Callable接口,并通过ExecutorService接口的submit方法获取返回的Future对象。 4. 使用FutureTask时,可以传入...

    Java中的Runnable,Callable,Future,FutureTask的比较

    Java中的Runnable、Callable、Future和FutureTask是Java多线程编程中的核心概念,它们各自扮演着不同的角色,共同协作以实现并发任务的管理和执行。 1. **Runnable**: Runnable是最基本的多线程接口,它只有一个`...

    揭密FutureTask.docx

    在Java并发编程中,FutureTask扮演着至关重要的角色,它是实现异步计算的关键组件。本文将深入探讨FutureTask的原理和用法,帮助开发者更好地理解和利用这个强大的工具。 一、Future接口与FutureTask概述 Future...

    Java线程超时监控

    本文将深入探讨Java中如何实现单个线程的执行超时监控。 首先,我们可以使用`java.util.concurrent`包中的`Future`和`ExecutorService`来实现线程超时。`ExecutorService`是一个接口,它提供了管理和控制线程池的...

    Java中Future、FutureTask原理以及与线程池的搭配使用

    `Future`接口提供了对异步计算结果的访问和控制,而`FutureTask`是`Future`的一个具体实现,它还同时实现了`Runnable`接口,因此可以直接提交给`Executor`执行。 `Future`接口提供了以下方法: 1. `boolean cancel...

    JAVA线程总结,包含线程池,显示使用线程实现异步编程,基于JDK中的Future实现异步编程,JDK中的FutureTask等

    JAVA线程总结,包含线程池,显示使用线程实现异步编程,基于JDK中的Future实现异步编程,JDK中的FutureTask等

    Java FutureTask类使用案例解析

    FutureTask类实现了RunnableFuture接口,RunnableFuture接口是Runnable和Future的综合体。 FutureTask类提供了一个runAndReset方法,该方法可以运行任务并重置Future的状态。 Callable和Runnable的转换可以使用...

    FutureTask:FutureTask原始解析与重组-源码解析

    FutureTask原始码解析 一,FutureTask是什么? FutureTask是可取消的异步的计算任务,它可以通过线程池和线程对象执行,一般来说是FutureTask用于耗时的计算。 二,FutureTask继承图 三,未来任务源码 FutureTask的...

    Java 多线程与并发(17-26)-JUC线程池- FutureTask详解.pdf

    `FutureTask`是Java并发库中的一个关键组件,它实现了`RunnableFuture`接口,能够作为`Runnable`接口的实现被线程执行,同时也继承了`Future`接口,用于获取计算的结果。`FutureTask`的设计使得我们可以更加灵活地...

    Android(Java)之多线程结果返回——Future 、FutureTask、Callable、Runnable

    `Future`、`FutureTask`、`Callable`和`Runnable`是Java并发编程中的核心接口和类,它们在Android开发中同样有着广泛的应用。下面将详细介绍这些概念以及它们如何协同工作。 1. `Runnable`: 这是Java中最基础的多...

    Android--开发--异步加载图像小结 (含线程池,缓存方法).rar

    - 使用`LruCache`或`WeakHashMap`实现内存缓存,存储图片的Bitmap对象。内存缓存速度快,但容量有限,需根据设备内存大小合理设置缓存容量。 2. 磁盘缓存: - 使用`DiskLruCache`或者`OkHttp`自带的`Cache`实现...

    tiny-asyncload:动态代理+延迟加载+futureTask的一种应用思路

    "tiny-asyncload"项目是一个基于动态代理和FutureTask实现的轻量级异步加载框架,它提供了一种优雅的方式去理解和应用这两种核心概念。下面将详细阐述这两个知识点及其在该框架中的应用。 首先,我们来看动态代理。...

    Demo_Android.rar_DEMO

    在"Demo_Android"项目中,可能会展示上述的一种或多种多线程实现方式。学习这个示例,你可以了解到如何在Android中创建和管理线程,如何在不同线程之间通信,以及如何避免ANR等问题。同时,实践项目中的代码,有助于...

Global site tag (gtag.js) - Google Analytics