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缓存框架实现对页面的缓存 本工程编码方式:UTF-8 本工程开发工具:MyEclipse 说明: 1、ehcache.xml和ehcache.xsd两个文件可以在下在下载下来的名为“ehcache-core-x.x.x-...
Java线程池FutureTask实现原理详解 Java线程池FutureTask实现原理详解是Java多线程编程中的一种重要机制,用于追踪和控制线程池中的任务执行。下面将详细介绍FutureTask的实现原理。 类视图 为了更好地理解...
FutureTask的实现机制是通过传入Runnable或者Callable的任务给FutureTask,然后调用其run方法或通过线程池执行,最后可以在外部通过FutureTask的get方法异步获取执行结果。 FutureTask还可以确保即使调用了多次run...
在这个简谈中,我们将深入探讨`FutureTask`的实现原理和使用方式。 首先,`FutureTask`实现了`Runnable`接口,这意味着它可以直接被`Executor`服务执行。同时,它也实现了`Future`接口,提供了检查任务是否完成、...
FutureTask 底层实现分析 FutureTask 是 Java 中的一种非常重要的多线程设计模式,用于异步计算线程之间的结果传递。在 JDK 中,FutureTask 类是 Future 模式的实现,它实现了 Runnable 接口,作为单独的线程运行。...
`FutureTask`是Java并发编程中的一个重要组件,它位于`java.util.concurrent`包下,是`Executor`框架的一部分。...在实际开发中,你可以根据需求选择适合的线程池,结合`FutureTask`实现复杂并发场景的解决方案。
`FutureTask`是`java.util.concurrent`包中的一个类,它实现了`Future`接口,允许我们执行一个任务并获取其结果。当我们提交一个`FutureTask`到线程池时,可以异步地执行任务,并在需要时获取结果。下面是一个使用`...
2.FutureTask可以接收Callable的实现类,也可以接收Runnable的实现类。 3. 使用Future时,需要实现Callable接口,并通过ExecutorService接口的submit方法获取返回的Future对象。 4. 使用FutureTask时,可以传入...
Java中的Runnable、Callable、Future和FutureTask是Java多线程编程中的核心概念,它们各自扮演着不同的角色,共同协作以实现并发任务的管理和执行。 1. **Runnable**: Runnable是最基本的多线程接口,它只有一个`...
在Java并发编程中,FutureTask扮演着至关重要的角色,它是实现异步计算的关键组件。本文将深入探讨FutureTask的原理和用法,帮助开发者更好地理解和利用这个强大的工具。 一、Future接口与FutureTask概述 Future...
本文将深入探讨Java中如何实现单个线程的执行超时监控。 首先,我们可以使用`java.util.concurrent`包中的`Future`和`ExecutorService`来实现线程超时。`ExecutorService`是一个接口,它提供了管理和控制线程池的...
`Future`接口提供了对异步计算结果的访问和控制,而`FutureTask`是`Future`的一个具体实现,它还同时实现了`Runnable`接口,因此可以直接提交给`Executor`执行。 `Future`接口提供了以下方法: 1. `boolean cancel...
JAVA线程总结,包含线程池,显示使用线程实现异步编程,基于JDK中的Future实现异步编程,JDK中的FutureTask等
FutureTask类实现了RunnableFuture接口,RunnableFuture接口是Runnable和Future的综合体。 FutureTask类提供了一个runAndReset方法,该方法可以运行任务并重置Future的状态。 Callable和Runnable的转换可以使用...
FutureTask原始码解析 一,FutureTask是什么? FutureTask是可取消的异步的计算任务,它可以通过线程池和线程对象执行,一般来说是FutureTask用于耗时的计算。 二,FutureTask继承图 三,未来任务源码 FutureTask的...
`FutureTask`是Java并发库中的一个关键组件,它实现了`RunnableFuture`接口,能够作为`Runnable`接口的实现被线程执行,同时也继承了`Future`接口,用于获取计算的结果。`FutureTask`的设计使得我们可以更加灵活地...
`Future`、`FutureTask`、`Callable`和`Runnable`是Java并发编程中的核心接口和类,它们在Android开发中同样有着广泛的应用。下面将详细介绍这些概念以及它们如何协同工作。 1. `Runnable`: 这是Java中最基础的多...
- 使用`LruCache`或`WeakHashMap`实现内存缓存,存储图片的Bitmap对象。内存缓存速度快,但容量有限,需根据设备内存大小合理设置缓存容量。 2. 磁盘缓存: - 使用`DiskLruCache`或者`OkHttp`自带的`Cache`实现...
"tiny-asyncload"项目是一个基于动态代理和FutureTask实现的轻量级异步加载框架,它提供了一种优雅的方式去理解和应用这两种核心概念。下面将详细阐述这两个知识点及其在该框架中的应用。 首先,我们来看动态代理。...
在"Demo_Android"项目中,可能会展示上述的一种或多种多线程实现方式。学习这个示例,你可以了解到如何在Android中创建和管理线程,如何在不同线程之间通信,以及如何避免ANR等问题。同时,实践项目中的代码,有助于...