synchronized
synchronized的效果
當一個線程訪問同步代碼塊的時候,會滿足以下條件:
- 同步代碼塊以前的代碼已經(jīng)被執(zhí)行完。
- 同步代碼塊以后的代碼,在同步代碼塊執(zhí)行結束之前不會被執(zhí)行。
- 當前沒有其他線程占有鎖資源
- synchronized中的變量的改變將會同步到內(nèi)存
synchronized的優(yōu)化
- 在Java 1.5以前是重鎖。
- 在Java 1.6以后,synchronized做了大量優(yōu)化:
- 在無鎖定狀態(tài)下是偏向鎖。 此時鎖會指定一個經(jīng)常訪問它的線程,這個線程訪問這個鎖時,不需要判斷鎖的狀態(tài)。
- 在有鎖狀態(tài)下是輕量級鎖。 當有線程要訪問這個鎖時,需要判斷這個線程的狀態(tài)。如果這個鎖被占用,線程進行自旋,等待鎖被釋放。
- 在輕量級鎖狀態(tài)下,自旋滿10次變成重量級鎖。 此時等待所釋放的線程進入阻塞狀態(tài),等待鎖釋放時喚醒。
synchronized實現(xiàn)原理
synchronized用的鎖是存在Java對象頭里的。對于成員方法,這個對象是當前的對象;對于靜態(tài)方法,這個方法是類對象;對于同步代碼塊,這個對象實在代碼中聲明的對象;

Java對象頭
當有線程訪問同步代碼或退出時,會去查看并改變鎖對象的Java頭。即JVM中的monitorenter和monitorexit指令。
優(yōu)化
synchronized本身對性能有一些消耗,所以應當注意:
- 盡量避免用鎖,對于本身不需要考慮線程安全的代碼,不需要添加鎖強制其同步;
- 選用合適的對象作為鎖(避免不相關代碼競爭同一個鎖);
- 鎖定的代碼區(qū)域盡可能的小,避免在不需要同步的地方阻塞
Android多線程(一)
Android多線程(二)
Android多線程(三)
Android多線程(四)
Android多線程(六)