1. 程式人生 > >一些小總結

一些小總結

1.sychronized
1>當執行緒 A 呼叫某物件的synchronized 方法 或者 synchronized 程式碼塊時,若同步鎖未釋放,其他執行緒呼叫同一物件的synchronized 方法 或者 synchronized 程式碼塊時將被阻塞,直至執行緒 A 釋放該物件的同步鎖。
2>synchronized 方法 和 synchronized 程式碼塊的不同之處在於 synchronized 方法 作用域較大,作用於整個方法,而 synchronized 程式碼塊 可控制具體的作用域,更精準控制提高效率。(畢竟阻塞的都是時間啊)
3>當執行緒 A 呼叫某物件的synchronized 方法 或者 synchronized 程式碼塊時,若同步鎖未釋放,其他執行緒呼叫同一物件的其他synchronized 方法 或者 synchronized 程式碼塊時將被阻塞,直至執行緒 A 釋放該物件的同步鎖。(注意:重點是其他)
4>當執行緒 A 呼叫某物件的synchronized 方法 或者 synchronized 程式碼塊時,無論同步鎖是否釋放,其他執行緒呼叫同一物件的其他 非 synchronized 方法 或者 非 synchronized 程式碼塊時可立即呼叫。
2.關於threadlocal
threadlocal存在一個執行緒裡面。也就是一個執行緒裡面的變數。可以保證執行緒安全。使用場景是在一個執行緒裡面put進去的值,在這個執行緒裡面的任何一個地方都可以用。缺點是傳值時可能過大。
看另外一個場景,一個請求過來,會帶有一堆的c引數(可以理解為客戶端的一些標誌),我們的應用處理過程中,大部分地方又不需要關心該引數,可能在某個請求他人介面的時候需要了,如果我們把所有程式碼都帶上這個c引數,那麼未免程式碼看著太過醜陋,這種情況下,我們可以構建一個filter,在請求過來的時候,在filter中將c引數放置到ThreadLocal中,在整個呼叫鏈中如果需要使用,直接從ThreadLocal中獲取即可。

3.關於Volatile
Volatile關鍵字主要的作用是把值強刷到記憶體中。一定程度上能保證執行緒安全,但是它不能保證原子性。主要的用處為:
boolean stop = false;
while(!stop){
doSomething();
}
//執行緒2
stop = true;
下面解釋一下這段程式碼為何有可能導致無法中斷執行緒。在前面已經解釋過,每個執行緒在執行過程中都有自己的工作記憶體,那麼執行緒1在執行的時候,會將stop變數的值拷貝一份放在自己的工作記憶體當中。
那麼當執行緒2更改了stop變數的值之後,但是還沒來得及寫入主存當中,執行緒2轉去做其他事情了,那麼執行緒1由於不知道執行緒2對stop變數的更改,因此還會一直迴圈下去。
不能保證原子性的為i++操作。
4.關於== 和 equal
1)對於==,如果作用於基本資料型別的變數,則直接比較其儲存的 “值”是否相等;
如果作用於引用型別的變數,則比較的是所指向的物件的地址
2)對於equals方法,注意:equals方法不能作用於基本資料型別的變數
如果沒有對equals方法進行重寫,則比較的是引用型別的變數所指向的物件的地址;
諸如String、Date等類對equals方法進行了重寫的話,比較的是所指向的物件的內容。
5.其實getParameter()和getAttribute()最簡單的兩點區別就是
1)賦值方式不一樣,前者是客戶端如瀏覽器端將請求引數值送給伺服器端,而後者則是在請求到達伺服器端之後,在伺服器進行存放進去
2)兩者的返回值型別不一樣,前者永遠返回字串,後者返回任意物件
既然parameter和attribute都是傳遞引數,為什麼不直接使用parameter呢?
原因有2:
1)從上面分析可以找到getParameter獲取的是客戶端傳送的引數,而且在伺服器端不能通過setParameter(key, value)來新增引數,因為沒有這個函式所以如果需要在伺服器端進行跳轉,並需要想下個頁面傳送新的引數時,則沒法實現。但是attribute可以,可以通過setAttribute(),將值放入到request物件,然後在其他頁面使用getAttribute獲取對應的值,這樣就達到一次請求可以在多個頁面共享一些物件資訊
2)parameter返回值是字串,意味著不能傳遞其他的物件,如List,但是attribute則可以存放任意型別的Java物件

問題:
dubbo是如何負載均衡的。
小財迷所用的dubbo版本為2.8.4
1.dubbo的叢集容錯:
<dubbo:service cluster="failfast"/>
屬性:cluster 型別:string 是否必須:可選 預設值:failover 作用:效能調優 可選方式:failover/failfast/failsafe/failback/forking 相容性:dubbo的2.0.5以上版本
1.1.failover(dubbo預設配置)
失敗自動切換,當出現失敗,重試其它伺服器(預設)。通常用於讀操作,但重試會帶來更長延遲。可通過retries="2"來設定重試次數(不含第一次),retries的值是根據你的服務部署了多少臺機器來設定的,比如你的同一個服務在三臺機器上都部署了,那麼retries的值就設定為2.如果設定為0,則相當於failfast了。 可以在消費端和服務提供端配置。
1.2.failfast
快速失敗,只發起一次呼叫,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。
可以在服務提供方和服務消費方都可以配置。如:
服務提供方:<dubbo:service cluster="failfast" /> 服務消費方:<dubbo:reference cluster="failfast" />
1.3.failsafe
失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作。服務提供方和服務消費方都可以。
1.4.failback
失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於訊息通知操作。服務提供方和服務消費方都可以。
1.5.forking
並行呼叫多個伺服器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過forks="2"來設定最大並行數。服務提供方和服務消費方都可以。
注意:一般情況下failover(讀操作)和failfast(寫操作)就可以滿足需求;failover叢集容錯的retries的屬性值改為"0"時等價於failfast、
2.dubbo的負載均衡:
2.1.Random
隨機,按權重設定隨機概率。在一個截面上碰撞的概率高,但呼叫量越大分佈越均勻,而且按概率使用權重後也比較均勻,有利於動態調整提供者權重。
2.2.RoundRobin
輪循,按公約後的權重設定輪循比率。存在慢的提供者累積請求問題,比如:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久之,所有請求都卡在調到第二臺上。
2.3.LeastActive
最少活躍呼叫數,相同活躍數的隨機,活躍數指呼叫前後計數差。使慢的提供者收到更少請求,因為越慢的提供者的呼叫前後計數差會越大。
2.4.ConsistentHash
一致性Hash,相同引數的請求總是發到同一提供者。當某一臺提供者掛時,原本發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引起劇烈變動。
配置方式:
<dubbo:service interface="..." loadbalance="roundrobin" />