java編碼:保證方法呼叫鏈的原子性
保證方法呼叫鏈的原子性
如果我們想建立一個物件的例項,而這個物件的例項是通過鏈式呼叫建立的。然後我們需要保證鏈呼叫的原子性。
請考慮以下示例:
public class ChainedMethod {
private int age=0;
private String name="";
private String adress="";
public ChainedMethod setAdress(String adress) {
this.adress = adress;
return this;
}
public ChainedMethod setAge(int age) {
this.age = age;
return this;
}
public ChainedMethod setName(String name) {
this.name = name;
return this;
}
}
一個非常簡單的物件,我們定義了三個屬性,每個時間集返回一個對此的引用。
https://club.lenovo.com.cn/thread-6601546-1-1.html
https://club.lenovo.com.cn/thread-6601557-1-1.html
https://club.lenovo.com.cn/thread-6601570-1-1.html
https://club.lenovo.com.cn/thread-6601817-1-1.html
https://club.lenovo.com.cn/thread-6601839-1-1.html
https://club.lenovo.com.cn/thread-6601855-1-1.html
https://club.lenovo.com.cn/thread-6601867-1-1.html
https://club.lenovo.com.cn/thread-6601882-1-1.html
https://club.lenovo.com.cn/thread-6601897-1-1.html
https://club.lenovo.com.cn/thread-6601916-1-1.html
https://club.lenovo.com.cn/thread-6601933-1-1.html
https://club.lenovo.com.cn/thread-6601984-1-1.html
https://club.lenovo.com.cn/thread-6601999-1-1.html
https://club.lenovo.com.cn/thread-6602020-1-1.html
https://club.lenovo.com.cn/thread-6602060-1-1.html
https://club.lenovo.com.cn/thread-6602088-1-1.html
https://club.lenovo.com.cn/thread-6602105-1-1.html
https://club.lenovo.com.cn/thread-6602117-1-1.html
https://club.lenovo.com.cn/thread-6602372-1-1.html
https://club.lenovo.com.cn/thread-6602396-1-1.html
https://club.lenovo.com.cn/thread-6602406-1-1.html
https://club.lenovo.com.cn/thread-6602417-1-1.html
https://club.lenovo.com.cn/thread-6602427-1-1.html
https://club.lenovo.com.cn/thread-6602435-1-1.html
https://club.lenovo.com.cn/thread-6602446-1-1.html
https://club.lenovo.com.cn/thread-6602467-1-1.html
https://club.lenovo.com.cn/thread-6602504-1-1.html
https://club.lenovo.com.cn/thread-6602520-1-1.html
https://club.lenovo.com.cn/thread-6602553-1-1.html
https://club.lenovo.com.cn/thread-6602591-1-1.html
https://club.lenovo.com.cn/thread-6602610-1-1.html
https://club.lenovo.com.cn/thread-6602623-1-1.html
https://club.lenovo.com.cn/thread-6602633-1-1.html
https://club.lenovo.com.cn/thread-6603123-1-1.html
https://club.lenovo.com.cn/thread-6603204-1-1.html
https://club.lenovo.com.cn/thread-6603239-1-1.html
https://club.lenovo.com.cn/thread-6603278-1-1.html
https://club.lenovo.com.cn/thread-6603319-1-1.html
https://club.lenovo.com.cn/thread-6603342-1-1.html
https://club.lenovo.com.cn/thread-6603371-1-1.html
https://club.lenovo.com.cn/thread-6603421-1-1.html
https://club.lenovo.com.cn/thread-6603494-1-1.html
https://club.lenovo.com.cn/thread-6603513-1-1.html
https://club.lenovo.com.cn/thread-6603572-1-1.html
https://club.lenovo.com.cn/thread-6603643-1-1.html
https://club.lenovo.com.cn/thread-6603688-1-1.html
https://club.lenovo.com.cn/thread-6603969-1-1.html
https://club.lenovo.com.cn/thread-6603984-1-1.html
https://club.lenovo.com.cn/thread-6604101-1-1.html
https://club.lenovo.com.cn/thread-6604188-1-1.html
https://club.lenovo.com.cn/thread-6604203-1-1.html
https://club.lenovo.com.cn/thread-6604226-1-1.html
https://club.lenovo.com.cn/thread-6604266-1-1.html
https://club.lenovo.com.cn/thread-6604297-1-1.html
https://club.lenovo.com.cn/thread-6604321-1-1.html
https://club.lenovo.com.cn/thread-6604351-1-1.html
https://club.lenovo.com.cn/thread-6604456-1-1.html
https://club.lenovo.com.cn/thread-6604482-1-1.html
https://club.lenovo.com.cn/thread-6604542-1-1.html
https://club.lenovo.com.cn/thread-6604644-1-1.html
https://club.lenovo.com.cn/thread-6604706-1-1.html
https://club.lenovo.com.cn/thread-6604983-1-1.html
https://club.lenovo.com.cn/thread-6604998-1-1.html
https://club.lenovo.com.cn/thread-6605111-1-1.html
https://club.lenovo.com.cn/thread-6605152-1-1.html
https://club.lenovo.com.cn/thread-6605172-1-1.html
https://club.lenovo.com.cn/thread-6605190-1-1.html
https://club.lenovo.com.cn/thread-6605207-1-1.html
https://club.lenovo.com.cn/thread-6605226-1-1.html
https://club.lenovo.com.cn/thread-6605254-1-1.html
https://club.lenovo.com.cn/thread-6605288-1-1.html
https://club.lenovo.com.cn/thread-6605357-1-1.html
https://club.lenovo.com.cn/thread-6605388-1-1.html
https://club.lenovo.com.cn/thread-6605423-1-1.html
https://club.lenovo.com.cn/thread-6605468-1-1.html
https://club.lenovo.com.cn/thread-6605513-1-1.html
https://club.lenovo.com.cn/thread-6605988-1-1.html
https://club.lenovo.com.cn/thread-6606015-1-1.html
https://club.lenovo.com.cn/thread-6606203-1-1.html
https://club.lenovo.com.cn/thread-6606251-1-1.html
https://club.lenovo.com.cn/thread-6606260-1-1.html
https://club.lenovo.com.cn/thread-6606274-1-1.html
https://club.lenovo.com.cn/thread-6606287-1-1.html
https://club.lenovo.com.cn/thread-6606300-1-1.html
https://club.lenovo.com.cn/thread-6606316-1-1.html
https://club.lenovo.com.cn/thread-6606359-1-1.html
https://club.lenovo.com.cn/thread-6606422-1-1.html
https://club.lenovo.com.cn/thread-6606445-1-1.html
https://club.lenovo.com.cn/thread-6606477-1-1.html
https://club.lenovo.com.cn/thread-6606521-1-1.html
https://club.lenovo.com.cn/thread-6606541-1-1.html
https://club.lenovo.com.cn/thread-6606934-1-1.html
https://club.lenovo.com.cn/thread-6606957-1-1.html
https://club.lenovo.com.cn/thread-6607669-1-1.html
https://club.lenovo.com.cn/thread-6607696-1-1.html
https://club.lenovo.com.cn/thread-6607711-1-1.html
https://club.lenovo.com.cn/thread-6607721-1-1.html
https://club.lenovo.com.cn/thread-6607729-1-1.html
https://club.lenovo.com.cn/thread-6607737-1-1.html
https://club.lenovo.com.cn/thread-6607749-1-1.html
https://club.lenovo.com.cn/thread-6607764-1-1.html
https://club.lenovo.com.cn/thread-6607773-1-1.html
https://club.lenovo.com.cn/thread-6607790-1-1.html
https://club.lenovo.com.cn/thread-6607804-1-1.html
https://club.lenovo.com.cn/thread-6607820-1-1.html
https://club.lenovo.com.cn/thread-6607836-1-1.html
https://club.lenovo.com.cn/thread-6608067-1-1.html
https://club.lenovo.com.cn/thread-6608103-1-1.html
https://mclub.lenovo.com.cn/thread-6592866-1-1.html
https://mclub.lenovo.com.cn/thread-6594212-1-1.html
https://mclub.lenovo.com.cn/thread-6594213-1-1.html
https://mclub.lenovo.com.cn/thread-6594216-1-1.html
https://mclub.lenovo.com.cn/thread-6594217-1-1.html
https://mclub.lenovo.com.cn/thread-6594220-1-1.html
https://mclub.lenovo.com.cn/thread-6594335-1-1.html
https://mclub.lenovo.com.cn/thread-6594337-1-1.html
https://mclub.lenovo.com.cn/thread-6594342-1-1.html
https://mclub.lenovo.com.cn/thread-6594344-1-1.html
https://mclub.lenovo.com.cn/thread-6594349-1-1.html
https://mclub.lenovo.com.cn/thread-6594353-1-1.html
讓我們看看如何在多執行緒環境中呼叫:
ChainedMethod chainedMethod= new ChainedMethod();
Thread t1 = new Thread(() -> chainedMethod.setAge(1).setAdress("www").setName("name1"));
t1.start();
Thread t2 = new Thread(() -> chainedMethod.setAge(2).setAdress("www2").setName("name2"));
t2.start();
因為在多執行緒環境下,上面設定的方法可能會比較混亂。怎麼解決?我們可以首先建立一個本地副本,這是執行緒安全的,因為它是在本地訪問的,最後將副本複製到新建立的例項物件。
主要程式碼如下:
public class ChainedMethodWithBuilder {
private int age=0;
private String name="";
private String adress="";
public ChainedMethodWithBuilder(Builder builder){
this.adress=builder.adress;
this.age=builder.age;
this.name=builder.name;
}
public static class Builder{
private int age=0;
private String name="";
private String adress="";
public static Builder newInstance(){
return new Builder();
}
private Builder() {}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setAdress(String adress) {
this.adress = adress;
return this;
}
public ChainedMethodWithBuilder build(){
return new ChainedMethodWithBuilder(this);
}
}
我們看下怎麼呼叫:
final ChainedMethodWithBuilder[] builder = new ChainedMethodWithBuilder[1];
Thread t1 = new Thread(() -> {
builder[0] =ChainedMethodWithBuilder.Builder.newInstance()
.setAge(1).setAdress("www").setName("name1")
.build();});
t1.start();
Thread t2 = new Thread(() ->{
builder[0] =ChainedMethodWithBuilder.Builder.newInstance()
.setAge(1).setAdress("www").setName("name1")
.build();});
t2.start();
因為lambda表示式中使用的變數必須是最終的或最終等價的,所以我們需要構建一個最終陣列。
讀寫64bits的值
在java中,64位長和double被視為兩個32位。
因此,64位的一個操作被分成32位的兩個操作。這就導致了原子問題。
請考慮以下程式碼:
public class LongUsage {
private long i =0;
public void setLong(long i){
this.i=i;
}
public void printLong(){
System.out.println("i="+i);
}
}
因為long的讀寫分為兩部分,如果在多執行緒環境中多次呼叫setLong和printLong的方法,可能會出現問題。
解決方法很簡單,長變數或雙變數都可以定義為volatile。
private volatile long i = 0;
相關文章
- Redis中的原子操作(2)-redis中使用Lua指令碼保證命令原子性Redis指令碼
- Redis 使用 Lua 指令碼替代 SETNX / DECR 保證原子性Redis指令碼
- 從JDK原始碼角度看併發的原子性如何保證JDK原始碼
- java安全編碼指南之:可見性和原子性Java
- 新姿勢!Redis中呼叫Lua指令碼以實現原子性操作Redis指令碼
- HTTP有哪些保證冪等性和安全性的方法? - mscharhagHTTP
- 區塊鏈真的能保證資料的完整性嗎? - Bozho區塊鏈
- Volatile不保證原子性及解決方案
- Java併發之原子性、有序性、可見性Java
- 如何保證MongoDB的安全性?MongoDB
- Spring Cloud中如何保證各個微服務之間呼叫的安全性SpringCloud微服務
- 軟體專案質量保證:編碼規範
- Java8新特性系列(原子性操作)Java
- 高階java必須清楚的概念:原子性、可見性、有序性Java
- 【java】【集合】set集合、唯一性保證、Linkset、案例Java
- 併發程式設計的原子性 != 事務ACID的原子性程式設計
- Spring Cloud中如何保證各個微服務之間呼叫的安全性(下篇)SpringCloud微服務
- TCP如何保證可靠性TCP
- java多執行緒3:原子性,可見性,有序性Java執行緒
- 雲端計算時代前端如何保證開原始碼的安全性前端原始碼
- Redis 中的原子操作(1)-Redis 中命令的原子性Redis
- 線上教育網站原始碼保證教學影片安全的方法網站原始碼
- 《RabbitMQ》如何保證訊息的可靠性MQ
- RabbitMQ如何保證訊息的可達性MQ
- Java基礎——方法的呼叫Java
- 如何優雅的編寫Java介面(安全性,可重複呼叫,穩定性,追溯性)Java
- Java核心知識體系8:Java如何保證執行緒安全性Java執行緒
- 如何保證介面的冪等性?
- java安全編碼指南之:方法編寫指南Java
- [深入理解Java虛擬機器]原子性/可見性/有序性Java虛擬機
- Android總結之鏈式呼叫(方法鏈)Android
- Kafka 如何保證訊息消費的全域性順序性Kafka
- Promise 原始碼:then 鏈式呼叫Promise原始碼
- 如何保證訊息佇列的順序性?佇列
- java中避免集合死鏈呼叫Java
- Java方法02:方法的定義和呼叫Java
- Java 併發程式設計(四):如何保證物件的執行緒安全性Java程式設計物件執行緒
- 元件事務的保證方法有幾多?元件