文章目录
菜鸟的一个学习笔记,欢迎大神 批评指正。
Java多线程相关知识【13】–设计模式–不可变对象模式
1.问题的引入
对于锁模式,由于要不断的加锁和解锁,而带来的重复操作的效率将会降低,加锁带来的多线程同时访问运行效率低下的问题,而要解决这种问题,则产生了一个不可变对象的概念。
2.引用的意义
只读对象其他引用对象的人没有任何机会修改相应的数据,通过这样的设计,能加速多线程在访问时的运行速度。
3.线程安全与可变对象和不可变对象的关系
S1.不可变对象一定是线程安全的
由于对象内的数据不可变,故元素内,拥有多线程进行操作时,不可变的对象的数据并不会被修改,所以是线程安全的。
S2.可变对象不一定是线程不安全的
当可变对象的公有方法都加锁时,自然就变成了线程安全的。
例如StringBuffer,而StringBuder中,并没有多数的锁,故StringBuffer是线程安全的,并且对象是可变的。
4.代码编写原则
1.类内的属性应全部为final修饰的类,确保数据无法被修改。
2.当前的类应为final的。
3.若要修改类不可变对象的值,只能将其重新赋值。
4.为防止元素获取到引用类型数据后,进行引用修改,可将引用的对象进行副本拷贝后返还给操作者。
5.实际编写示例
/**
* 字符串统计类,可进行字符串统计
* <p>
* 传入一个字符串,会将相应的字符串进行统计
*/
public final class StringCountNotModify {
private final String sourceString;
private final int upper;
private final int lower;
private final int number;
/**
* 构造时进行数据统计,当数据输入后,相关的数据将无法修改
*
* @param sourceString
*/
public StringCountNotModify(final String sourceString) {
this.sourceString = sourceString;
int upper = 0;
int lower = 0;
int number = 0;
char[] s = sourceString.toCharArray(); //转换为字符数组
for (char c :
s) {
if (Character.isUpperCase(c)) upper++; //大写,大写统计+1
else if (Character.isLowerCase(c)) lower++; //小写,小写统计+1
else if (Character.isDigit(c)) number++; //数字,数字统计+1
}
this.lower = lower;
this.upper = upper;
this.number = number;
}
/**
* 获取传入的数据
*
* @return 传入的数据
*/
public String getSourceString() {
return sourceString;
}
/**
* 获取统计的大写字母数
*
* @return 大写字母数
*/
public int getUpper() {
return upper;
}
/**
* 获取统计的小写字母数
*
* @return 大写字母数
*/
public int getLower() {
return lower;
}
/**
* 获取统计的数字的个数
*
* @return 大写字母数
*/
public int getNumber() {
return number;
}
/**
* 默认输出相关内容
*
* @return 要输出的内容
*/
@Override
public String toString() {
return "StringCount{" +
"sourceString='" + sourceString + '\'' +
", upper=" + upper +
", lower=" + lower +
", number=" + number +
'}';
}
}