第一次寫技術(shù)文檔,因為擔(dān)心很多以前做過的東西,又要接著做一遍。所以開始寫一些東西記錄一下。
問題:如果寫一個接口,其他人調(diào)用這個結(jié)果的時候,根據(jù)接口的參數(shù)來加鎖。
環(huán)境:因為沒有寫demo 的習(xí)慣,所以都是直接在真實項目里面做的示例。
后臺:Spring boot 寫的接口
前臺:vue 寫的網(wǎng)絡(luò)請求
話不多說:上代碼
@GetMapping(value = "/he/{username}")
public String setexcle2(@PathVariable String username) {
StringBuffer sb=new StringBuffer();
sb.append(username);
synchronized(sb.toString().intern()) {
System.out.println(username);
try {
//延時3秒執(zhí)行
Thread.currentThread().sleep(3000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
String username2 = username + "運算結(jié)果:::::: ";
System.out.println(username2);
}
return "你好!世界" + username;
}
這個就是一個get請求的接口:接口地址是 本機ip:8080/main/he,當然這個不重要。重要的是里面的方法。

這就是關(guān)鍵。
原因是
再看String
JVM內(nèi)存區(qū)域里面有一塊常量池,關(guān)于常量池的分配:
JDK6的版本,常量池在持久代PermGen中分配
JDK7的版本,常量池在堆Heap中分配
字符串是存儲在常量池中的,有兩種類型的字符串數(shù)據(jù)會存儲在常量池中:
1.編譯期就可以確定的字符串,即使用""引起來的字符串,比如String a = "123"、String b = "1" + B.getStringDataFromDB() + "2" + C.getStringDataFromDB()、這里的"123"、"1"、"2"都是編譯期間就可以確定的字符串,因此會放入常量池,而B.getStringDataFromDB()、C.getStringDataFromDB()這兩個數(shù)據(jù)由于編譯期間無法確定,因此它們是在堆上進行分配的
2.使用String的intern()方法操作的字符串,比如String b = B.getStringDataFromDB().intern(),盡管B.getStringDataFromDB()方法拿到的字符串是在堆上分配的,但是由于后面加入了intern(),因此B.getStringDataFromDB()方法的結(jié)果,會寫入常量池中
3.常量池中的String數(shù)據(jù)有一個特點:每次取數(shù)據(jù)的時候,如果常量池中有,直接拿常量池中的數(shù)據(jù);如果常量池中沒有,將數(shù)據(jù)寫入常量池中并返回常量池中的數(shù)據(jù)。
因此回到我們之前的場景,使用StringBuilder拼接字符串每次返回一個new的對象,但是使用intern()方法則不一樣:
接下來就是測試了:
在vue里面進行測試,我們循環(huán)5次,每次里面放2個請求,一個相同,一個不同。看看執(zhí)行的結(jié)果。
posthttp(){
let that = this;
for(var i=0;i<5;i++){
that.$http({
url: "http://localhost:8090/main/he/哇哈哈"+(i),
method: 'get',
}).then((res) => {
console.log(res);
}).catch((res) => {
console.log('SideSec.vue :', res);
});
that.$http({
url: "http://localhost:8090/main/he/測試",
method: 'get',
}).then((res) => {
console.log(res);
}).catch((res) => {
console.log('SideSec.vue :', res);
});
}
最后我們執(zhí)行這個vue程序 。
npm run dev

最后我們看看控制臺的打印

可以看出 請求參數(shù)為測試的 都是加了鎖 同步的。哇哈哈1 哇哈哈2 就是沒有同步的。
忽然感覺寫的很爛,準備把名字改了。

這樣我們就能看出這里李四是同步了的。