多執行緒設計模式-不可變物件設計模式
阿新 • • 發佈:2021-01-03
技術標籤:java併發程式設計多執行緒設計模式設計模式設計模式多執行緒java
不可變物件設計模式
無鎖狀態的設計,比有鎖的設計模式減少加鎖和釋放鎖的時間消耗
- 不可變物件一定是執行緒安全的:裡面的任何屬性或者引用型別的屬性都不能被修改
- 可變物件不一定是執行緒不安全的:StringBuffer
Final關鍵字
1、final修飾的成員變數只能初始化一次賦值。1:直接賦值 2:建構函式中賦值
final修飾的成員變數是基本型別,不可被修改,引用型別也如此,地址不可被修改,但是引用物件裡面的資料是可以被修改的
2、final修飾的類,是不可被繼承的,成員方法都會被隱式指定為final型別方法,一般工具類使用final關鍵字使用
3、private方法被隱式final修飾的,如果父類的方法時final修飾的,子類不能去重寫
package com.ln.concurrent.chapter7;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.chapter7
* @version: 1.0
*/
import java.util.Collections;
import java.util.List;
/**
* @ClassName:ImmutableTest
* @Author:linianest
* @CreateTime:2020/3/25 13:23
* @version:1.0
* @Description TODO: 不可變物件的方法屬性
*/
/**
* 1、final修飾的成員變數只能初始化一次賦值。1:直接賦值 2:建構函式中賦值
* final修飾的成員變數是基本型別,不可被修改,引用型別也如此,地址不可被修改,但是引用物件裡面的資料是可以被修改的
* 2、final修飾的類,是不可被繼承的,成員方法都會被隱式指定為final型別方法,一般工具類使用final關鍵字使用
* 3、private方法被隱式final修飾的,如果父類的方法時final修飾的,子類不能去重寫
*/
public class ImmutableTest {
private final int age;
private final String name;
private final List<String> list;
public ImmutableTest(int age, String name, List<String> list) {
this.age = age;
this.name = name;
this.list = list;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
/**
* 如果不想返回的list被別人修改,可以返回不可變的集合
* @return
*/
public List<String> getList() {
return Collections.unmodifiableList(list);
}
}
可變物件與可變物件在多執行緒狀態下的效能對比
package com.ln.concurrent.chapter7;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.chapter7
* @version: 1.0
*/
/**
* @ClassName:ImmutablePerformance
* @Author:linianest
* @CreateTime:2020/3/25 13:36
* @version:1.0
* @Description TODO: 不可變物件與可變物件加鎖的效能對比
*/
public class ImmutablePerformance {
public static void main(String[] args) {
// sync 51520
long startTimestamp = System.currentTimeMillis();
// SyncObj syncObj = new SyncObj();
// syncObj.setName("Alex");
// immutable 29729
ImmutableObj immutableObj = new ImmutableObj("Alex");
for (long i = 0L; i <1_000_000 ; i++) {
System.out.println(immutableObj.toString());
}
long endTimestamp = System.currentTimeMillis();
System.out.println("Elasped time "+(endTimestamp-startTimestamp));
}
}
/**
* 定義不可變物件
*/
final class ImmutableObj {
private final String name;
public ImmutableObj(String name) {
this.name = name;
}
@Override
public String toString() {
return "[" + name + "]";
}
}
// 可變物件
class SyncObj {
private String name;
public synchronized void setName(String name) {
this.name = name;
}
@Override
public synchronized String toString() {
return "[" + name + "]";
}
}