- 浏览: 63137 次
- 性别:
- 来自: 成都
文章分类
最新评论
一个简单的学习多线程缓存的demo:
//计算 public interface Computable<A, V> { V compute(A arg) throws InterruptedException; } /** 第一种最简单实现:采用HashMap,直接在compute()方法上加锁这种构建缓存的方式有很大问题, * 如果compute执行时间很长那么有很多线程都要排队等待,那么此时效率可能比没有缓存还低.*/ public class Momizer1<A, V> implements Computable<A, V>{ private final Map<A, V> cacheMap = new HashMap<A, V>(); private final Computable<A, V> computable; public Momizer1(Computable<A, V> computable){ this.computable = computable; } @Override public synchronized V compute(A arg) throws InterruptedException { V v = cacheMap.get(arg); if(v==null){ v = computable.compute(arg); cacheMap.put(arg, v); } return v; } } /** 第二种实现:用ConcurrentHashMap代替HashMap,由于ConcurrentHashMap是线程安全的且效率比较高,所以比第一种效率高. * 但是这种方式会产生重复计算问题,假如传入相同的值,因为线程间不知道是否已经开始计算,所以都会去计算。*/ public class Momizer2<A, V> implements Computable<A, V>{ private final ConcurrentHashMap<A, V> cacheMap = new ConcurrentHashMap<A, V>(); private final Computable<A, V> computable; public Momizer2(Computable<A, V> computable){ this.computable = computable; } @Override public V compute(A arg) throws InterruptedException { V v = cacheMap.get(arg); if(v==null){ v = computable.compute(arg); cacheMap.put(arg, v); } return v; } } /** 第三种实现:将长时间的计算过程用FutureTask替代,如果FutureTask计算结果完毕,那么直接返回结果, * 如果没有那么久阻塞等待返回结果.但是这种方式还是没有解决重复计算问题,虽然概率远小于第二种方式.因为 * 存在符合操作若没有则添加*/ public class Momizer3<A, V> implements Computable<A, V>{ private final ConcurrentHashMap<A, FutureTask<V>> cacheMap = new ConcurrentHashMap<A, FutureTask<V>>(); private final Computable<A, V> computable; public Momizer3(Computable<A, V> computable){ this.computable = computable; } @Override public V compute(final A arg) throws InterruptedException { FutureTask<V> futureTask = cacheMap.get(arg); // if(futureTask==null){ Callable<V> callable = new Callable<V>() { @Override public V call() throws Exception { return computable.compute(arg); } }; FutureTask<V> f = new FutureTask<>(callable); futureTask = f; cacheMap.put(arg, f); f.run(); /*futureTask = new FutureTask<>(callable); cacheMap.put(arg, futureTask); futureTask.run();*/ } try { return futureTask.get(); } catch (ExecutionException e) { throw new RuntimeException(); } } } /** * 第四种实现:利用ConcurrentHashMap的putIfAbsent方法实现,这个方法相当于如果有就返回值,没有就返回null并讲值放入map. */ public class Momizer4<A, V> implements Computable<A, V> { private final ConcurrentHashMap<A, FutureTask<V>> cacheMap = new ConcurrentHashMap<A, FutureTask<V>>(); private final Computable<A, V> computable; public Momizer4(Computable<A, V> computable) { this.computable = computable; } @Override public V compute(final A arg) throws InterruptedException { while(true){ FutureTask<V> f = cacheMap.get(arg); if(f==null){ Callable<V> callable = new Callable<V>() { @Override public V call() throws Exception { return computable.compute(arg); } }; FutureTask<V> ft = new FutureTask<>(callable); f = cacheMap.putIfAbsent(arg, ft); if(f==null){f=ft;ft.run();} } try { return f.get(); } catch (CancellationException e) { //如果FutureTask调用了取消那么清除缓存重新循环放入 cacheMap.remove(arg); }catch (ExecutionException e) { e.printStackTrace(); } } } }
发表评论
-
读ThreadLocal源代码
2017-10-12 15:00 239//可以存取线程局部变量 //先看构造函数 pub ... -
读Exchanger源码
2017-10-10 11:38 332//用于线程间交换数据 public V exchang ... -
读Executors源码
2017-09-29 15:23 260//一个管理线程创建的类里面都是静态方法 //创建一 ... -
读ScheduledThreadPoolExecutor源码
2017-09-25 17:33 414//一个可以延迟执行的定时任务 //先看构造函数 构造函 ... -
读部分ThreadPoolExecutor源码
2017-09-25 15:27 304//线程池 //先看构造方法 public Threa ... -
读AbstractExecutorService
2017-09-23 16:34 324//他是ExecutorService的部分实现 pub ... -
读ExecutorCompletionService源码
2017-09-23 11:22 485//一个用来管理已完成任务的service,内部封装了一个 ... -
读FutureTask源码
2017-09-22 16:45 269//一个可以异步返回计算的结果 //它同时实现了Futu ... -
读ConcurrentSkipListMap源码
2017-09-21 15:11 289//数据结构是跳表 关于数据结构http://blog.c ... -
读Semaphore源码
2017-09-09 14:58 292//一个信号量,只有在池中还拥有许可时才允许线程继续执行。 ... -
读CyclicBarrier源码
2017-09-01 17:59 344//一个循环的屏障。所有的线程在屏障处等待其他线程执行完毕 ... -
读CountDownLatch源码
2017-09-01 14:01 321//在完成一组操作之前允许一个或多个线程等待内部用的AQS ... -
读ConcurrentLinkedQueue
2017-09-01 11:40 286//这是一个无阻塞的队列没有加任何锁全部利用CAS机制实现 ... -
读ConcurrentHashMap源码
2017-08-31 11:21 274//先看构造函数 public ConcurrentHa ... -
读CopyOnWriteArrayList源码
2017-08-22 12:59 407//在该集合上的写操作都是在原有的副本上进行的操作。这样可 ... -
读LinkedBlockingDeque源码
2017-08-21 14:26 561//这是一个支持双端操作的可阻塞队列 //先看构造函数 ... -
读SynchronousQueue源码
2017-08-10 10:51 374//先看构造方法 public SynchronousQ ... -
读PriorityBlocking源码
2017-08-09 13:47 353//一个基于而为堆的优先级队列,它是无界的。 //先看构 ... -
读DelayQueen源码
2017-08-07 15:16 274//一个基于二叉堆优先 ... -
LinkedblockingQueue源码解读
2017-08-04 13:03 348//LinkedBlockQueue //先看构造函数 ...
相关推荐
在本项目中,我们探索了如何将Spring MVC框架与多线程、线程池和Apache Kafka集成,构建一个高效的数据处理系统。以下是关于这些技术及其整合的详细知识点: 1. **Spring MVC**: - Spring MVC是Spring框架的一个...
- `lock`关键字提供了一种简单的方法来锁定特定对象,确保同一时间只有一个线程可以访问。 - `volatile`关键字用于标记变量,确保所有线程都能看到最新的值,避免缓存导致的问题。 4. **线程池**: - .NET框架中...
这个DEMO是一个很好的学习案例,它演示了如何在实际应用中结合多线程、URLSession和表格单元格复用来优化图片加载,提升用户体验。通过分析和理解这个DEMO,开发者可以更好地掌握iOS应用中的异步处理和性能优化技巧...
Bitmap图片的三级缓存DEMO是一个典型的应用实例,旨在提高图片加载速度并减少内存消耗。这里我们将深入探讨“三级缓存”、“强引用”和“软引用”这三个核心概念,并通过BitmapUtils三层缓存的实现来阐述它们如何...
在这个demo中,我们可以学习如何设置和使用HTML5离线缓存,以及如何结合Web Workers来创建一个离线可用且响应快速的Web应用。通过阅读博客文章(http://blog.csdn.net/mockingbirds/article/details/48412967),...
2. **并发控制**:在多线程环境中,我们需要确保缓存的读写操作是线程安全的。可以使用锁机制,如互斥锁(Mutex)或读写锁(Read-Write Lock),或者使用无锁数据结构,如Java中的ConcurrentHashMap。 3. **分布式...
在iOS开发中,多图片多线程下载是一个常见的需求,特别是在构建富媒体应用程序时。这个“ios开发-iOS开发实用demo之多图片多线程下载实例”提供了如何在iOS应用中实现这一功能的具体示例。以下是对这个示例中涉及的...
总结,学习JNI层多线程回调Java方法,主要涉及以下几点: 1. 理解JNI的基本使用,包括定义和实现native方法。 2. 在多线程环境中正确使用`JNIEnv`,如在新线程中创建新的JNI环境并附加到Java虚拟机。 3. 了解`...
这个"TestAnything"的Demo可能涵盖了以上提到的某些或全部知识点,每个Demo都是一个具体的应用场景,通过实践这些Demo,开发者可以更好地理解和掌握Android开发的关键技术,从而提升自己的开发能力。同时,作者提醒...
ASimpleCache是一个轻量级的缓存框架,旨在简化Android应用中的数据缓存操作。它提供了简单易用的API,让开发者能够快速地在应用程序中集成缓存功能,提高应用性能,减少网络请求,降低服务器压力。这个压缩包包含了...
读文件费时间,所以开一个线程读文件。 抽象后的类似demo: 假定读文件需要0.6秒,图像处理(用存文件代替)需要0.5秒,各执行100次。 类和函数 读取文件函数: 一,List增加本序号(0开始)。 二,随机生成5000...
磁盘缓存则可以存储更多的图片,即使应用关闭后也能快速加载。 6. **异步处理**:图片加载应在后台线程进行,防止UI卡顿。可以使用AsyncTask、Loader或者现代的协程库如Kotlin Coroutines来实现。 7. **内存泄漏...
在多线程编程中,确保线程安全是至关重要的,特别是在资源访问方面。"一对多锁"是一种设计模式,用于管理多个线程对共享资源的访问,特别适用于一写多读...学习这个DEMO将有助于理解多线程编程中同步和优化的关键概念。
这个Demo项目涵盖了多个关键知识点,包括异步加载、网络编程、JSON解析以及LruCache图片缓存策略,这些都是在实际开发中处理数据流和用户体验优化的重要技术。 1. **异步加载**: 在Android中,为了防止UI线程被...
线程池是多线程编程中的一个重要概念,它是一种线程使用模式,旨在优化系统资源的使用并提高系统的响应速度。在Java中,线程池通过`java.util.concurrent`包中的`ExecutorService`接口和其相关类实现。下面将详细...
6:使用状态模式 观察者模式更好的处理多线程 最初的想法:网络优化开发框架 (移除任务未完成) 网络稳定,系统运行稳定性,大内存消耗稳定,长时间运行稳定性 (旧的系统症结所在) 开启过多线程,导致系统...
内存缓存通常使用NSCache类,它是一个轻量级的对象缓存系统,当系统内存不足时,会自动清除部分数据。磁盘缓存则通常使用沙盒中的特定文件夹来存储数据,例如SQLite数据库、文件系统或者使用第三方库如SDWebImage...
描述中提到“很好用的多线程图片加载,里面有DEMO及Library”,这意味着该项目提供了一个实用的解决方案,并且包含了示例代码(DEMO)以及库文件(Library),开发者可以直接引用和学习。DEMO是演示如何在实际应用中...
1. 继承Thread类:创建一个新的类,继承自Thread类,并重写其run()方法。然后通过创建该类的实例并调用start()方法来启动线程。 2. 实现Runnable接口:创建一个实现了Runnable接口的类,实现run()方法。然后将...
接下来,我们将创建一个简单的缓存服务,封装常用的操作: ```csharp public class RedisCacheService { private readonly RedisConnection _connection; public RedisCacheService() { _connection = ...