跟着实例学习java多线程7-对象的组合发布
来源:互联网 发布:老司机求网址 知乎 编辑:程序博客网 时间:2024/06/06 02:17
我们学习线程安全与同步的知识目的就是要实现一些可复用组件或编写出更大的程序。
java中类是对象抽象,那么怎么实现一个线程安全类是我们必须要知道的并正确使用的技术。
在设计线程安全类的过程中,需要包含以下三个基本元素:
找出构成对象状态的所有变量。
找出约束状态变量的不变性条件。
建立对象状态的并发访问管理策略。
package com.home.thread.thread7;import com.home.thread.safe;public class Counter {/** * @author gaoxu * */public class SafeThread {private int id = 0;@safepublic synchronized int getId(){if(id==Integer.MAX_VALUE)throw new IllegalStateException("counter overflow");return ++id;}}}
方法getId被原子化,这里主要是因为id的状态判断是一个约束条件,而这个约束条件决定了id的值的有效性,所以必须对这步操作做原子化处理。
实例封闭
我们在编写程序中多数会使用一些非线程安全的对象来实现数据的存储,这样的对象如果被多线程访问或是写入,那么就必须做线程安全处理,最好的方式是线程中的封闭处理。让我们来看一个经常会用到的实例:
package com.uskytec.ubc.foundation.queue;import java.util.LinkedList;import com.uskytec.ubc.foundation.entity.SmsSubmitEntity;/**保存到短信猫的信息的队列 * @author GaoXu * */public class LNSentCache {private static LNSentCache instance = null;public synchronized static LNSentCache getInstance(){if (instance == null)instance = new LNSentCache();return instance;}private final static LinkedList<SmsSubmitEntity> routeCache = new LinkedList<SmsSubmitEntity>();/** * 添加到指定缓冲池 * @param type * @param smgpConfigID * @param submitMsg * @return */public synchronized int add(SmsSubmitEntity sms){routeCache.add(sms);return 1;}/** * 得到指定缓冲池的的对象 * @param sgipConfigID * @return */public synchronized Object get(){ if (routeCache != null&&routeCache.size()>0) return routeCache.removeFirst(); return null;}}
我们利用LinkedList来实现一个先进先出队列,但是LinkedList不是线程安全的,所以我们把它进行实例封闭,这样任何一个线程都可以访问它的值。
线程安全性委托
我们经常会使用ConcurrentHashMap这样的并发对象,它们是java提供的并发变成对象,它们在内部实现了同步机制,所以它们是线程安全的,我们可以把不安全对象Map的访问完全交给它来委托管理,这样通过final类型的处理,我们只需要通过Collections的浅拷贝实现Map的线程安全。
实例我们先不提供,大家可以回去试着写一下,下一节我们在来讨论。
利用现有线程安全的类实现并发添加功能
java api中有很多这样的类,例如:Vector、HashTable等,让我们来看一个例子。
package com.gome.qiantai.tools;import java.util.Vector;import com.gome.qiantai.service.IAppraiseWriterObserverService;/** * @author gaoxu * */public class ObserverCache {private static ObserverCache instance = null;public synchronized static ObserverCache getInstance(){if (instance == null)instance = new ObserverCache();return instance;}private static Vector<IAppraiseWriterObserverService> obs = new Vector<IAppraiseWriterObserverService>();public Vector<IAppraiseWriterObserverService> getObs(){return obs;}}
我们利用Vector来实现了一个监听器列表的操作。
同步类是我们在实践中经常要实现的类,我们要多思考这样的问题,我的类需要写成线程安全的吗?
- 跟着实例学习java多线程7-对象的组合发布
- 跟着实例学习java多线程6-如何正确发布线程安全的对象
- 跟着实例学习java多线程2-synchronized锁住的是对象还是代码
- 跟着实例学习java多线程1-为什么使用?
- 跟着实例学习java多线程4-内存可见性
- 跟着实例学习java多线程5-初识volatile变量
- 跟着实例学习java多线程9-并发容器
- 跟着实例学习java多线程3-synchronized的多种写法有何区别?
- 跟着实例学习java多线程8-同步容器类的问题
- 跟着实例学习java多线程10-定时任务实例Quartz等
- 跟着实例学习ZooKeeper的用法: Barrier
- 跟着实例学习ZooKeeper的用法: 计数器
- 跟着实例学习ZooKeeper的用法: 队列
- 跟着实例学习ZooKeeper的用法: 缓存
- 跟着实例学习ZooKeeper的用法: 计数器
- 跟着实例学习ZooKeeper的用法: Barrier
- 跟着实例学习ZooKeeper的用法: 队列
- 跟着实例学习ZooKeeper的用法: 计数器
- ARC Semantic issue:No visiable @interface for xxx declares the selector yyy编译错误
- iOS开发中编译通过Success但有红色警告
- Linux设备模型 (1)
- IOS TableView 用法
- 劝君惜取少年时
- 跟着实例学习java多线程7-对象的组合发布
- 没有重写 归档和反归档的方法 编译报错
- 线程:避免死锁
- 2.2工作日志
- LeetCode 8.String to Integer (atoi)
- USB 知识整理合辑
- sign签名参数值无效,解决办法
- 普通位运算
- javassist 学习笔记