Java知識(shí)點(diǎn)隨記

Volatile

Java語(yǔ)言提供了一種稍弱的同步機(jī)制,即valatile變量,用來(lái)確保將變量的更新操作通知到其他線(xiàn)程。當(dāng)把變量聲明為valtile類(lèi)型后,編譯器與運(yùn)行時(shí)都會(huì)注意到這個(gè)變量是共享的,因此不會(huì)將該變量上的操作與其他內(nèi)存操作一起重排序??傊?,volatile變量是一種比sychronized關(guān)鍵字更輕量級(jí)的同步機(jī)制。
僅當(dāng)volatile變量能簡(jiǎn)化代碼的實(shí)現(xiàn)以及對(duì)同步策略的驗(yàn)證時(shí),才應(yīng)該使用它們。volatile變量的正確使用方式包括:確保它們自身狀態(tài)的可見(jiàn)性,確保它們所引用對(duì)象的狀態(tài)的可見(jiàn)性,以及標(biāo)識(shí)一些重要的程序生命周期事件的發(fā)生。
volatile變量通常用做某個(gè)操作完成、發(fā)生中斷或者狀態(tài)的標(biāo)志。

volatile boolean asleep;
...
while (!asleep) {
    ...
}

普通變量和volatile變量的區(qū)別是:volatile的特殊規(guī)則保證了新值能立即同步到主內(nèi)存,以及每次使用前立即從主內(nèi)存刷新。因此,可以說(shuō)volatile保證了多線(xiàn)程操作時(shí)變量的可見(jiàn)性,而普通變量則不同保證這一點(diǎn)。

Java內(nèi)存模型

Java內(nèi)存模型是圍繞著在并發(fā)過(guò)程中如何處理原子性、可見(jiàn)性和有序性這3個(gè)特征來(lái)建立的。

原子性
可見(jiàn)性

可見(jiàn)性是指當(dāng)一個(gè)線(xiàn)程修改了共享變量的值,其他線(xiàn)程能夠立即得知這個(gè)修改。
除了volatile之外,Java還有兩個(gè)關(guān)鍵字能實(shí)現(xiàn)可見(jiàn)性,即synchronized和final。同步塊的可見(jiàn)性是由“對(duì)一個(gè)變量執(zhí)行unlock操作之前,必須先把此變量同步回主內(nèi)存中(執(zhí)行store、write操作)”這條規(guī)則獲得的,而final關(guān)鍵字可見(jiàn)性是指:被final修改的字段在構(gòu)造器中一旦初始化完成,并且構(gòu)造器沒(méi)有把“this”的引用傳遞出去,那在其他線(xiàn)程中就能夠看見(jiàn)final字段的值。

有序性

如果在本線(xiàn)程內(nèi)觀(guān)察,所有的操作都是有序的;如果在一個(gè)線(xiàn)程中觀(guān)察另一個(gè)線(xiàn)程,所有的操作都是無(wú)序的。前半句是指“線(xiàn)程內(nèi)表現(xiàn)為串行的語(yǔ)義”,后半句是指“指令重排序”現(xiàn)象和“工作內(nèi)存與主內(nèi)存同步延遲”現(xiàn)象。
Java語(yǔ)言提供了volatile和synchronized兩個(gè)關(guān)鍵字來(lái)保證線(xiàn)程之間操作的有序性,volatile關(guān)鍵字本身就包含了禁止指令重排序的語(yǔ)義,而synchronized則是由“一個(gè)變量在同一時(shí)刻只允許一條線(xiàn)程對(duì)其進(jìn)行l(wèi)ock操作”這條規(guī)則獲得的,這條規(guī)則決定了持有同一個(gè)鎖的兩個(gè)同步塊只能串行的進(jìn)入。

先行發(fā)生原則

Java語(yǔ)言中有一個(gè)“先行發(fā)生”(happens-before)的原則,這個(gè)原則非常重要,它是判斷數(shù)據(jù)是否存在競(jìng)爭(zhēng)、線(xiàn)程是否安全的主要依據(jù),依靠這個(gè)原則,我們可以通過(guò)幾條規(guī)則一攬子地解決并發(fā)環(huán)境下兩個(gè)操作之間是否可能存在沖突的所有問(wèn)題。
先行發(fā)生是Java內(nèi)存模型中定義的兩項(xiàng)操作之間的偏序關(guān)系,如果說(shuō)操作A先行發(fā)生于操作B,其實(shí)就是說(shuō)發(fā)生操作B之前,操作A發(fā)生的影響能被操作B觀(guān)察到,“影響”包括修改了內(nèi)存中共享變量的值、發(fā)送了消息、調(diào)用了方法等。

Session和Cookie

Session合Cookie都是回話(huà)(Session)跟蹤技術(shù)。Cookie通過(guò)在客戶(hù)端記錄信息確定用戶(hù)身份,Session通過(guò)在服務(wù)器端記錄信息確定用戶(hù)身份。但是Session的實(shí)現(xiàn)依賴(lài)于Cookie,SessionId(session的唯一標(biāo)識(shí)需要存放在客戶(hù)端)。

  • cookie數(shù)據(jù)存放在客戶(hù)的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上
  • cookie不是很安全,別人可以分析存放在本地的COOKIE并進(jìn)行COOKIE欺騙,考慮到安全應(yīng)當(dāng)使用session
  • session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪(fǎng)問(wèn)增多,會(huì)比較占用你服務(wù)器的性能,考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用cookie。
  • 單個(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。

所以個(gè)人建議:將登陸信息等重要信息存放為session;其他信息如果需要保留,可以放在cookie中,比如購(gòu)物車(chē)。

事務(wù)

事務(wù)是并發(fā)控制的單位,是用戶(hù)定義的一個(gè)操作序列。這些操作要么都做,要么都不做,是一個(gè)不可分割的工作單位。

  • 原子性:表示事務(wù)內(nèi)操作不可分割,要么都成功,要么都失敗
  • 一致性:要么都成功,要么都失敗,后面的失敗了要對(duì)前面的操作進(jìn)行回滾
  • 隔離性:一個(gè)事務(wù)開(kāi)始后,不么受其他事務(wù)干擾
  • 持久性:表示事務(wù)開(kāi)始了就不能終止

Spring總結(jié)

控制誰(shuí)?當(dāng)然是IoC 容器控制了對(duì)象;
控制什么?那就是主要控制了外部資源獲?。ú恢皇菍?duì)象包括比如文件等)。
因?yàn)橛扇萜鲙臀覀儾檎壹白⑷胍蕾?lài)對(duì)象,對(duì)象只是被動(dòng)的接受依賴(lài)對(duì)象,所以是反轉(zhuǎn);
哪些方面反轉(zhuǎn)了?依賴(lài)對(duì)象的獲取被反轉(zhuǎn)了。

  • 誰(shuí)依賴(lài)于誰(shuí):當(dāng)然是應(yīng)用程序依賴(lài)于IoC容器;
  • 為什么需要依賴(lài):應(yīng)用程序需要IoC容器來(lái)提供對(duì)象需要的外部資源;
  • 誰(shuí)注入誰(shuí):很明顯是IoC容器注入應(yīng)用程序某個(gè)對(duì)象,應(yīng)用程序依賴(lài)的對(duì)象;
  • 注入了什么:就是注入某個(gè)對(duì)象所需要的外部資源(包括對(duì)象、資源、常量數(shù)據(jù))。

IoC和DI由什么關(guān)系呢?其實(shí)它們是同一個(gè)概念的不同角度描述,由于控制反轉(zhuǎn)概念比較含糊,所以又給出了一個(gè)新的名字:“依賴(lài)注入”,相對(duì)IoC 而言,“依賴(lài)注入”明確描述了“被注入對(duì)象依賴(lài)IoC容器配置依賴(lài)對(duì)象”。
<context:component-scan base-package="com.yonyou.yls"/>在xml配置了這個(gè)標(biāo)簽后,spring可以自動(dòng)掃描base-package下面或者子包下面的java文件,如果掃描到有@Component @Controller @Service @Repository等這些注解的類(lèi),則把這些類(lèi)注冊(cè)為bean。
Use-dafault-filters=”false”的情況下:<context:exclude-filter>指定的不掃描,<context:include-filter>指定的掃描
<mvc:annotation-driven/>是告知Spring,我們啟用注解驅(qū)動(dòng)。然后Spring會(huì)自動(dòng)為我們注冊(cè)上面說(shuō)到的幾個(gè)Bean到工廠(chǎng)中,來(lái)處理我們的請(qǐng)求。
配置Spring和Spring Mvc,主要有:
1.在web.xml中配置好Spring相關(guān)Listener/Filter/Servlet,并指明Spring和Spring Mvc的配置文件,當(dāng)然,也可以不指定,放在classpath下就行,嚴(yán)謹(jǐn)一點(diǎn)還是寫(xiě)出來(lái)為好。
2.配置applicationContext.xml,這個(gè)是給Spring用的,名字隨意,只要在web.xml指定就行。
3.配置 spring-servlet.xml,這個(gè)是給Spring Mvc用的,名字隨意,只要在web.xml指定就行。

transient

java 的transient關(guān)鍵字為我們提供了便利,你只需要實(shí)現(xiàn)Serilizable接口,將不需要序列化的屬性前添加關(guān)鍵字transient,序列化對(duì)象的時(shí)候,這個(gè)屬性就不會(huì)序列化到指定的目的地中。像銀行卡、密碼等等這些數(shù)據(jù)。這個(gè)需要根據(jù)業(yè)務(wù)情況了。被transient修飾后不會(huì)被序列化。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容