1.什么是Immutability

Immutability,不变性,

叫做不变性设计模式,简单来说就是对象一旦创建,状态就不再发生变化。

变量一旦被赋值,就不允许修改了(没有写操作);没有修改操作,就保持了不变性

2.什么情况用Immutablity设计模式

多个线程同时读写同一个共享变量存在并发问题,核心条件是读写,如果只有读,没有写,是没有并发问题的

解决并发问题,最简单的办法就是让共享变量只有读操作,没有写操作。

3.快速实现具备不可变的类

将一个雷的所有属性都设置为final,并且只允许存在只读方法,那么这个类基本上就具备不可变性了。并且这个类本身也是final的,这个类本身不允许继承。

4.jdk中使用Immutablity设计模式的,不可变的类

Long,String


public final class String {
private final char value[];
// 字符替换
String replace(char oldChar,
char newChar) {
//无需替换,直接返回this
if (oldChar == newChar){
return this;
} int len = value.length;
int i = -1;
/* avoid getfield opcode */
char[] val = value;
//定位到需要替换的字符位置
while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
//未找到oldChar,无需替换
if (i >= len) {
return this;
}
//创建一个buf[],这是关键
//用来保存替换后的字符串
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ?
newChar : c;
i++;
}
//创建一个新的字符串返回
//原字符串不会发生任何变化
return new String(buf, true);
}
}

String中的可变方法,往往是新new 出一个新不可变对象来实现,会不会浪费内存呢?会的

5.如何解决内存浪费,使用享元模式

Long,Integer,Short,Byte 等这些基本数据类型的包装类都使用了享元模式

Long使用享元模式的范例(本质上是一个对象池或者缓存池的概念)


Long valueOf(long l) {
final int offset = 128;
// [-128,127]直接的数字做了缓存
if (l >= -128 && l <= 127) {
return LongCache
.cache[(int)l + offset];
}
return new Long(l);
}
//缓存,等价于对象池
//仅缓存[-128,127]直接的数字
static class LongCache {
static final Long cache[]
= new Long[-(-128) + 127 + 1]; static {
for(int i=0; i<cache.length; i++)
cache[i] = new Long(i-128);
}
}

String,Integer类也是类似

6.使用享元模式的这些包装类为什么不适合用于锁?

是因为有些看起来像是私有的锁,其实是共有的

伪代码,看着像是两把锁,其实是同一把锁


class A {
Long al=Long.valueOf(1);
public void setAX(){
synchronized (al) {
//省略代码无数
}
}
}
class B {
Long bl=Long.valueOf(1);
public void setBY(){
synchronized (bl) {
//省略代码无数
}
}
}

7.Immutability模式注意事项

  • 对象的所有属性都是final的,并不能保证不可变性
  • 不可变对象也需要正确发布

    final修饰的普通对象,对象属性是可以被修改的

8.正确使用Immutability的姿势

public final class ServerConfig {

    private final int masterExecThreads = 100;
private final int masterExecTaskNum = 20;
private final int listenPort = 5678;
private final String address = NetUtils.getAddr(listenPort); public String getAddress() {
return address;
} public int getMasterExecThreads() {
return masterExecThreads;
} public int getMasterExecTaskNum() {
return masterExecTaskNum;
} public int getListenPort() {
return listenPort;
}
}

设计模式Immutability的更多相关文章

  1. 作为一名双非本科毕业的Java程序员,我该如何在日益严重的内卷化中避免被裁?

    前言 对一个 Java 程序员而言,并发编程能否熟练掌握是判断他是不是优秀的重要标准之一.因为并发编程在 Java 语言中最为晦涩的知识点,它涉及内存.CPU.操作系统.编程语言等多方面的基础能力,更 ...

  2. 并发设计模式:Immutability模式

    多个线程同时读写同一共享变量存在并发问题,其中的必要条件之一就是 读写 ,如果没有写,只存在读,是不会存在并发问题的. 如果让一个共享变量只有读操作,没有写操作,如此则可以解决并发问题.该理论的具体实 ...

  3. 设计模式之构建者模式(Builder):初步理解

    构建者(Builder)设计模式(又叫生成器设计模式): 当一个类的内部数据过于复杂的时候(通常是负责持有数据的类,比如Config.VO.PO.Entity...),要创建的话可能就需要了解这个类的 ...

  4. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  5. java EE设计模式简介

    1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...

  6. 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式

    上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...

  7. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

  8. 《JavaScript设计模式与开发实践》整理

    最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...

  9. 设计模式之行为类模式大PK

                                        行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...

随机推荐

  1. vagrant构建centos虚拟环境

    vagrant搭建centos 什么是vagrant 如何使用 1.构建本地的目录 2.官方下载对应的镜像文件,官方下载地址 3.导入刚刚下载的镜像(box文件) 4.初始化 5.修改Vagrantf ...

  2. 脱壳——UPX脱壳原理(脱壳helloworld)

    脱壳--UPX脱壳原理 脱壳步骤 1 找到OEP 2 dump(导出)内存文件 3 修复 1 找到OEP 1 程序运行先从壳代码运行,壳代码执行完之后会跳转到真正的OEP,也就是是说第一步,首先要找到 ...

  3. postgresql高级应用之行转列&汇总求和

    postgresql高级应用之行转列&汇总求和 轉載請注名出處 https://www.cnblogs.com/funnyzpc/p/14732165.html 前言 节前公司业务方需要做一個 ...

  4. 详谈lastIndex对正则结果的影响

    前言 今天遇到一个问题,用正则表达式去检查同一个字符串时,交替返回true和false.无奈之下,重新翻了翻权威指南,发现罪魁祸首原来是lastIndex.可在控制台尝试下 ? 1 2 3 4 5 6 ...

  5. 【译】android的审计和hacking工具

    原文:Best Android Tools For Security Audit and Hacking android系统占移动市场份额的80%且有恶意软件,这是一个问题.Hacker会对手机恶意操 ...

  6. spring-boot-maven-plugin not found的解决方案

    spring-boot-maven-plugin not found 在maven测试的生命周期都没有错,但是就是爆红 参考了很多的链接,没有成功解决,最后得到真正有帮助的方法,添加springboo ...

  7. 并发容器-CopyOnWriteSet

    CopyOnWriteSet 该容器与CopyOnWriteArrayList相似,也是读取时不加锁,任意线程可以读.写入时加锁创建一个新的容器,然后写入新元素. 内部用CopyOnWriteArra ...

  8. Linux 中如何使用 IP 命令

    老版本的 Linux 中都是使用 ifconfig 命令检查和配置网络接口,但是该命令目前已经没有维护了,取而代之的是 ip 命令 ip 命令和 ifconfig 命令很相似,但是 相比起来,ip命令 ...

  9. 大华摄像头报警接口中图片加密,python调用c++方式实现解密

    项目中,大华摄像头的报警信息,里面有图片地址,需要1天内取下来,保持留痕 可惜,图片下载后,加密了,大华提供了android,ios,c++例子,没有提供java解密例子 没办法,只好先用c++例子简 ...

  10. [BUAA2021软工]结对第一阶段博客作业小结

    作业链接 结对项目-第一阶段 优秀作业推荐 本次博客作业虽然是简单总结,但是以下作业中都不乏有思考.有亮点的精彩内容,推荐给同学们阅读学习. 山鸣谷应,相得益彰--杰对项目-第一阶段总结 该组对于可能 ...