第一次寫技術(shù)文檔绅喉,因?yàn)閾?dān)心很多以前做過的東西茶敏,又要接著做一遍。所以開始寫一些東西記錄一下痊班。
問題:如果寫一個(gè)接口,其他人調(diào)用這個(gè)結(jié)果的時(shí)候哲鸳,根據(jù)接口的參數(shù)來(lái)加鎖臣疑。
環(huán)境:因?yàn)闆]有寫demo 的習(xí)慣,所以都是直接在真實(shí)項(xiàng)目里面做的示例徙菠。
后臺(tái):Spring boot 寫的接口
前臺(tái):vue 寫的網(wǎng)絡(luò)請(qǐng)求
話不多說(shuō):上代碼
@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 {
//延時(shí)3秒執(zhí)行
Thread.currentThread().sleep(3000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
String username2 = username + "運(yùn)算結(jié)果:::::: ";
System.out.println(username2);
}
return "你好讯沈!世界" + username;
}
這個(gè)就是一個(gè)get請(qǐng)求的接口:接口地址是 本機(jī)ip:8080/main/he,當(dāng)然這個(gè)不重要。重要的是里面的方法婿奔。
這就是關(guān)鍵缺狠。
原因是
再看String
JVM內(nèi)存區(qū)域里面有一塊常量池,關(guān)于常量池的分配:
JDK6的版本萍摊,常量池在持久代PermGen中分配
JDK7的版本挤茄,常量池在堆Heap中分配
字符串是存儲(chǔ)在常量池中的,有兩種類型的字符串?dāng)?shù)據(jù)會(huì)存儲(chǔ)在常量池中:
1.編譯期就可以確定的字符串冰木,即使用""引起來(lái)的字符串穷劈,比如String a = "123"、String b = "1" + B.getStringDataFromDB() + "2" + C.getStringDataFromDB()片酝、這里的"123"囚衔、"1"、"2"都是編譯期間就可以確定的字符串雕沿,因此會(huì)放入常量池练湿,而B.getStringDataFromDB()、C.getStringDataFromDB()這兩個(gè)數(shù)據(jù)由于編譯期間無(wú)法確定审轮,因此它們是在堆上進(jìn)行分配的
2.使用String的intern()方法操作的字符串肥哎,比如String b = B.getStringDataFromDB().intern(),盡管B.getStringDataFromDB()方法拿到的字符串是在堆上分配的疾渣,但是由于后面加入了intern()篡诽,因此B.getStringDataFromDB()方法的結(jié)果,會(huì)寫入常量池中
3.常量池中的String數(shù)據(jù)有一個(gè)特點(diǎn):每次取數(shù)據(jù)的時(shí)候榴捡,如果常量池中有杈女,直接拿常量池中的數(shù)據(jù);如果常量池中沒有吊圾,將數(shù)據(jù)寫入常量池中并返回常量池中的數(shù)據(jù)达椰。
因此回到我們之前的場(chǎng)景,使用StringBuilder拼接字符串每次返回一個(gè)new的對(duì)象项乒,但是使用intern()方法則不一樣:
接下來(lái)就是測(cè)試了:
在vue里面進(jìn)行測(cè)試啰劲,我們循環(huán)5次,每次里面放2個(gè)請(qǐng)求檀何,一個(gè)相同蝇裤,一個(gè)不同廷支。看看執(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/測(cè)試",
method: 'get',
}).then((res) => {
console.log(res);
}).catch((res) => {
console.log('SideSec.vue :', res);
});
}
最后我們執(zhí)行這個(gè)vue程序 恋拍。
npm run dev
最后我們看看控制臺(tái)的打印
可以看出 請(qǐng)求參數(shù)為測(cè)試的 都是加了鎖 同步的。哇哈哈1 哇哈哈2 就是沒有同步的啃憎。
忽然感覺寫的很爛芝囤,準(zhǔn)備把名字改了。
這樣我們就能看出這里李四是同步了的辛萍。