您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何正確的在java中使用同步鎖,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
同步鎖分類
對象鎖(this)
類鎖(類的字節碼文件對象即類名.class)
字符串鎖(比較特別)
應用場景
在多線程下對共享資源的安全操作。
需求:啟動5個線程對共享資源total進行安全操作。
同步鎖在多線程單例模式下的使用
以上三類同步鎖都可以。
package cn.myThread; public class MyThread implements Runnable { private static int total = 10; @Override public void run() { synchronized (this){ //使用this對象鎖 //synchronized (MyThread.class){ //使用MyThread.class類鎖 //synchronized (""){//使用字符串鎖 System.out.println(Thread.currentThread().getName() + "正在運行"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } total--; System.out.println(total); System.out.println(Thread.currentThread().getName() + "線程結束"); } } } package cn.test; import cn.myThread.MyThread; public class TestMyThread { public static void main(String[] args){ MyThread myThread = new MyThread(); Thread thread = null; for (int i = 1 ; i <= 5 ; i++){ thread = new Thread(myThread,"線程"+i); //開啟5個線程,傳入同一個對象 thread.start(); } } } 線程1正在運行 9 線程1線程結束 線程3正在運行 8 線程3線程結束 線程5正在運行 7 線程5線程結束 線程2正在運行 6 線程2線程結束 線程4正在運行 5 線程4線程結束
分析:從運行結果可以看出5個線程串行執行同步鎖里面的代碼,因為5個線程中的同步鎖對象this指向同一個的對象(同步鎖對象MyThread.class類鎖是同一個對象、同步鎖對象 ”” 字符串鎖是同一個對象),所以5個線程會串行執行同步鎖里面的代碼。
同步鎖在多線程多例模式下的使用
錯誤用法
package cn.myThread; public class MyThread implements Runnable { private static int total = 10; @Override public void run() { synchronized (this){//使用this對象鎖 System.out.println(Thread.currentThread().getName() + "正在運行"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } total--; System.out.println(total); System.out.println(Thread.currentThread().getName() + "線程結束"); } } } package cn.test; import cn.myThread.MyThread; public class TestMyThread { public static void main(String[] args){ Thread thread = null; for (int i = 1 ; i <= 5 ; i++){ thread = new Thread(new MyThread(),"線程"+i);//開啟5個線程,傳入5個不同對象 thread.start(); } } } 線程2正在運行 線程1正在運行 線程3正在運行 線程5正在運行 線程4正在運行 9 7 9 8 線程1線程結束 線程5線程結束 線程2線程結束 線程3線程結束 6 線程4線程結束
分析:從運行結果可以看出5個線程并行執行同步鎖里面的代碼,因為5個線程中的同步鎖對象this指向5個不同的對象,所以5個線程會同時執行同步鎖里面的代碼。
正確用法
方式一:
package cn.myThread; public class MyThread implements Runnable { private static int total = 10; @Override public void run() { synchronized (MyThread.class){//使用MyThread.class類鎖 System.out.println(Thread.currentThread().getName() + "正在運行"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } total--; System.out.println(total); System.out.println(Thread.currentThread().getName() + "線程結束"); } } } package cn.test; import cn.myThread.MyThread; public class TestMyThread { public static void main(String[] args){ Thread thread = null; for (int i = 1 ; i <= 5 ; i++){ thread = new Thread(new MyThread(),"線程"+i); //開啟5個線程,傳入5個不同對象 thread.start(); } } } 線程1正在運行 9 線程1線程結束 線程5正在運行 8 線程5線程結束 線程4正在運行 7 線程4線程結束 線程3正在運行 6 線程3線程結束 線程2正在運行 5 線程2線程結束
分析:從運行結果可以看出5個線程串行執行同步鎖里面的代碼,因為5個線程中的同步鎖對象MyThread.class類鎖是同一個對象,所以5個線程會串行執行同步鎖里面的代碼。
方式二:
package cn.myThread; public class MyThread implements Runnable { private static int total = 10; @Override public void run() { synchronized (""){//使用字符串鎖 System.out.println(Thread.currentThread().getName() + "正在運行"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } total--; System.out.println(total); System.out.println(Thread.currentThread().getName() + "線程結束"); } } } package cn.test; import cn.myThread.MyThread; public class TestMyThread { public static void main(String[] args){ Thread thread = null; for (int i = 1 ; i <= 5 ; i++){ thread = new Thread(new MyThread(),"線程"+i); //開啟5個線程,傳入5個不同對象 thread.start(); } } } 線程1正在運行 9 線程1線程結束 線程4正在運行 8 線程4線程結束 線程5正在運行 7 線程5線程結束 線程3正在運行 6 線程3線程結束 線程2正在運行 5 線程2線程結束
分析:從運行結果可以看出5個線程串行執行同步鎖里面的代碼,因為5個線程中的同步鎖對象 ”” 字符串鎖是同一個對象,所以5個線程會串行執行同步鎖里面的代碼。
關于如何正確的在java中使用同步鎖就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。