Java多线程——不可变对象
不可变对象条件
对象需要满足一下三个条件才是不可变对象:
1、对象创建以后其状态就不能修改
2、对象所有域都是final类型
3、对象是正确创建的(对象在创建期间,this引用没有溢出)
简而言之就是将类声明为final,将所有的成员声明为私有的,对变量不提供set方法。将所有可变的成员声明为final。在get方法中不返回对象本身,而是克隆对象的拷贝。(可参考String类)。
final关键字
final关键字可修饰类、方法和变量。在修饰类时,这个类是不允许被继承。final类中的方法会被隐式的被指定为final方法。修饰方法是为了锁定方法不被继承类修改,即final方法不允许被修改,一个类的private方法会被隐式指定为final类型。final修饰变量可分为两种情况。一、修饰基本数据类型时,一旦被final修饰,这个变量的数值就不能被修改了。二、修饰引用类型变量时,则是让它在初始化之后就不能指向其他对象(可修改该引用变量的成员变量)。例如:
@Slf4j
public class ImmutableExample1 { private final static Integer a = 1;
private final static String b = "2";
private final static Map<Integer, Integer> map = new HashMap(); static {
map.put(1, 2);
map.put(3, 4);
map.put(5, 6);
} public static void main(String[] args) {
map.put(1, 3);
log.info("{}", map.get(1));
}
}
虽然map声明为final对象,但是依然可以往里放入键值对。
Java提供常见不可变对象
Collections.unmodifiableXXX:Collection、List、Set、Map等。
@Slf4j
public class ImmutableExample2 { private static Map<Integer, Integer> map = Maps.newHashMap(); static {
map.put(1, 2);
map.put(3, 4);
map.put(5, 6);
map = Collections.unmodifiableMap(map);
} public static void main(String[] args) {
map.put(1, 3);
log.info("{}", map.get(1));
} }
执行结果如下:

发现执行结果为抛出异常信息,不允许被修改。我们可以用这个方法来修饰不可变的集合对象。
查看源码的主要方法实现:
public class Collections {
// Suppresses default constructor, ensuring non-instantiability.
private Collections() {
}
private final Map<? extends K, ? extends V> m;
UnmodifiableMap(Map<? extends K, ? extends V> m) {
if (m==null)
throw new NullPointerException();
this.m = m;
}
... ...
public V put(K key, V value) {
throw new UnsupportedOperationException();
}
public V remove(Object key) {
throw new UnsupportedOperationException();
}
public void putAll(Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
public void clear() {
throw new UnsupportedOperationException();
}
... ...
}
其实就是将put方法等直接抛出异常,防止修改。
其他工具提供的不可变对象
Googel常用的工具包Guava同样也提供了很多不可变对象的方法如 ImmutableXXX:Collection、List、Set、Map等。
Java多线程——不可变对象的更多相关文章
- 从火箭发场景来学习Java多线程并发闭锁对象
从火箭发场景来学习Java多线程并发闭锁对象 倒计时器场景 在我们开发过程中,有时候会使用到倒计时计数器.最简单的是:int size = 5; 执行后,size—这种方式来实现.但是在多线程并发的情 ...
- Java多线程操作同一个对象,线程不安全
Java多线程操作同一个对象 发现问题:多个线程操作同一资源的情况下,线程不安全,数据紊乱 代码: package multithreading; // Java多线程操作同一个对象 // 买火车票的 ...
- Java多线程编程核心技术---对象及变量的并发访问(二)
数据类型String的常量池特性 在JVM中具有String常量池缓存的功能. public class Service { public static void print(String str){ ...
- java String不可变对象,但StringBuffer是可变对象
什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不 ...
- java 多线程访问同一个对象数据保护的问题
java 多线程同时访问统一个数据的时候,会引起一些错误,后面的线程会修改数据,而前面的线程还在使用修改前的内容, 使用 synchronized 关键字,保证代码块只能有一个线程来访问 public ...
- Java多线程对同一个对象进行操作
示例: 三个窗口同时出售20张票. 程序分析: 1.票数要使用一个静态的值. 2.为保证不会出现卖出同一张票,要使用同步锁. 3.设计思路:创建一个站台类Station,继承THread,重写run方 ...
- java多线程系列(二)---对象变量并发访问
对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...
- Java多线程编程核心技术---对象及变量的并发访问(一)
synchronized同步方法 "非线程安全"其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是"脏读",也就是渠道的数据其实是被更改 ...
- Java多线程之释放对象的锁
由于等待一个锁定线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不需要锁的时候及时释放锁是很重要的.在以下情况下,持有锁的线程会释放锁: 1. 执行完同步代码块. 2. 在执行 ...
随机推荐
- 12、Django实战第12天:课程机构列表页数据展示
今天完成的是课程机构列表页.... 1.启动服务,进入xadmin后,添加5个城市信息用作测试数据 2.添加课程机构,其中有一项要上传封面图的地方要注意 封面图上传路径是我们在models中设置好的 ...
- RPD Volume 172 Issue 1-3 December 2016 评论04 end
这一篇作为本期的结束是因为发现后面的一些基本上也是EPR有关的会议内容, Contribution of Harold M. Swartz to In VivoEPR and EPR Dosimetr ...
- [BZOJ 1912] patrol 巡逻
Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1912 Algorithm: K=0:res=(n-1)*2 每条边恰好走2遍 K=1 ...
- iOS 文字渐变色
// 创建UILabel UILabel *label = [[UILabel alloc] init]; label.text = @"我是渐变的label"; [label s ...
- hdu2829 四边形优化dp
Lawrence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- 在WPF 4.5中跨线程更新集合
WPF中一个非常强大的功能是数据绑定,我们可以把一个集合绑定到ListBox中,当集合的数据发生变更时,ListBox界面也会同步变更.本身这是一个非常美好的事情,但是美中不足的是:当把集合绑定到Li ...
- "__doPostBack”未定义的解决办法(转载)
"__doPostBack”未定义,在IE下调试错误: 问题是服务器版的.Net40的补丁没有打上,ASP.NET 可能无法辨识出一些浏览器的最新版本,还会经常把它们看做是低级的浏览器,不支 ...
- SqlServer_删除重复行只保留一条记录
前提:相同的数据重复往数据库写入,导致存在仅主键Id不同的重复数据,现在需要去除重复数据,仅保留重复数据中Id最大的一条 思路: 1.找出存在重复数据的记录,并取重复数据中最大的Id值 2.删 ...
- Intellij IDEA System.out.println输出中文乱码问题
进行下列设置即可:
- IIS5/6/7 ASP.net 请求处理过程
tks:http://www.cnblogs.com/TomXu/p/3756774.html 主要内容 本文讲解的是:服务器接受Http Request请求之后,是如何进入.Net CLR,从而进一 ...