JAVA synchronized关键字锁机制(中)
synchronized 鎖機制簡單的用法,高效的執行效率使成為解決線程安全的首選。 下面總結其特性以及使用技巧,加深對其理解。
特性:
1. Java語言的關鍵字,當它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多只有一個線程執行該段代碼。
? ? ? 2. 當一個線程同時訪問object的一個synchronized(this)同步代碼塊時,其它線程仍然可以訪問非修飾的方法或代碼塊。
? ? ? 3. 當多個線程同時訪問object的synchronized(this)同步代碼塊時,會存在互斥訪問,其它線程會阻塞直到獲取鎖。
? ? ? 4. 當線程訪問object的synchronized(this)同步代碼塊時,同一個線程可以多次獲取鎖,當然也不需要釋放多次。獲取和釋放必須相同。
? ? ? 5. 所有的對象都可以獲取鎖,也可以釋放鎖。
? ? ? 6. 所有的類也可以獲取鎖和釋放鎖,因此靜態方法也可以加鎖。而特性同上。
猜想:
? ? ?在jvm中對每個對象都有一個記錄鎖的狀態,當同一個線程訪問鎖時候就會累加,其它線程訪問要等到狀態變為未鎖狀態,當讓相同線程釋放鎖會累減。
?質疑:
? ? 那么對于類鎖來說,應該是所有對象都可以獲取鎖,那么鎖是全局的對所有對象都有效?
public class SynchronizedMtdTest {public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {SynchronizedMtdTest.appendStr();}}).start();new Thread(new Runnable() {@Overridepublic void run() {SynchronizedMtdTest.printStr();}}).start();new Thread(new Runnable() {@Overridepublic void run() {SynchronizedMtdTest synchronizedMtdTest = new SynchronizedMtdTest();synchronizedMtdTest.appendStr();}}).start();new Thread(new Runnable() {@Overridepublic void run() {SynchronizedMtdTest synchronizedMtdTest = new SynchronizedMtdTest();synchronizedMtdTest.printStr();}}).start();new Thread(new Runnable() {@Overridepublic void run() {SynchronizedMtdTest synchronizedMtdTest = new SynchronizedMtdTest();synchronizedMtdTest.append();}}).start();}public synchronized static void appendStr() {System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr------");try {Thread.sleep(1000);System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr1000------");} catch (InterruptedException e) {e.printStackTrace();}}public static void append() {System.out.println("pid=" + Thread.currentThread().getId() + "------append------");try {Thread.sleep(3000);System.out.println("pid=" + Thread.currentThread().getId() + "------append3000------");} catch (InterruptedException e) {e.printStackTrace();}}public synchronized static void printStr() {System.out.println("pid=" + Thread.currentThread().getId() + "------printStr------");try {Thread.sleep(6000);System.out.println("pid=" + Thread.currentThread().getId() + "------printStr6000------");} catch (InterruptedException e) {e.printStackTrace();}}}結果:
pid=10------appendStr------ pid=14------append------ pid=10------appendStr1000------ pid=13------printStr------ pid=14------append3000------ pid=13------printStr6000------ pid=12------appendStr------ pid=12------appendStr1000------ pid=11------printStr------ pid=11------printStr6000------?分析結果可以看出對于靜態方法加鎖,所有的線程調用方法,不管怎樣都會互斥,而為加鎖不會互斥。
因此:
? ? 對于類鎖來說應該在持久代也就是方法區有對具體類也有加鎖機制,而且原理同對象鎖。
那么:
? ? 可見,上面可以做如下修改達到相同效果。
public static void appendStr() {synchronized (SynchronizedMtdTest.class) {System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr------");try {Thread.sleep(1000);System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr1000------");} catch (InterruptedException e) {e.printStackTrace();}}}public static void printStr() {synchronized (SynchronizedMtdTest.class) {System.out.println("pid=" + Thread.currentThread().getId() + "------printStr------");try {Thread.sleep(6000);System.out.println("pid=" + Thread.currentThread().getId() + "------printStr6000------");} catch (InterruptedException e) {e.printStackTrace();}}}?結果:
pid=10------appendStr------ pid=10------appendStr1000------ pid=13------printStr------ pid=13------printStr6000------ pid=12------appendStr------ pid=12------appendStr1000------ pid=11------printStr------ pid=11------printStr6000------?
轉載于:https://www.cnblogs.com/maybo/p/7560754.html
總結
以上是生活随笔為你收集整理的JAVA synchronized关键字锁机制(中)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2018车主信用卡哪家好?这三张车主卡权
- 下一篇: [BZOJ] 1688: [Usaco2