微軟 Win11 Cloud PC 雲電腦早期圖片曝光:“開始”選單按鈕還在左下角
阿新 • • 發佈:2021-07-13
Synchronized的三種應用方法
1.修飾例項方法,作用於當前例項加鎖,進入同步程式碼前要獲得當前例項的鎖
2.修飾靜態方法,作用於當前類物件加鎖,進入同步程式碼前要獲得當前類物件的鎖
3.修飾程式碼塊,指定枷鎖物件,對給定物件加鎖,進入同步程式碼庫前要獲得給定物件的鎖
1.synchronized作用於例項方法
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; public synchronized void increase(){ j++; } @Override public void run() { for (int i = 0; i < 1000000; i++) { increase(); } } public static void main(String[] args) throws InterruptedException { AccountingSynchronized accountingSynchronized = new AccountingSynchronized(); Thread t1= new Thread(accountingSynchronized); Thread t2 = new Thread(accountingSynchronized); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(j); } }
結果為2000000
2.這是兩個執行緒對共享變數進行操作,new了兩個不同的例項物件,存在兩個不同的例項物件鎖,兩者都會進入各自的物件鎖,他們兩個使用的不是同一把鎖,執行緒安全無法保證
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; public synchronized void increase(){ j++; } @Override public void run() { for (int i = 0; i < 1000000; i++) { increase(); } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new AccountingSynchronized()); Thread thread2 = new Thread(new AccountingSynchronized()); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(j); } }
解決方法:Synchronized作用於靜態方法
其鎖的物件是當前類的class物件
當將
public synchronized void increase(){j++;}
變為
public static synchronized void increase(){j++;}
結果又變成2000000
3.Synchronized同步程式碼塊
程式碼塊
static AccountingSynchronized instance = new AccountingSynchronized();
synchronized (instance) {}
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; static AccountingSynchronized instance = new AccountingSynchronized(); @Override public void run() { synchronized (instance) { for (int i = 0; i < 1000000; i++) { j++; } } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(j); }
synchronized (this) {}//this,當前例項鎖
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; @Override public void run() { synchronized (this) { for (int i = 0; i < 1000000; i++) { j++; } } } public static void main(String[] args) throws InterruptedException { AccountingSynchronized instance = new AccountingSynchronized(); Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(j); } }
AccountingSynchronized.class//class物件鎖
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; @Override public void run() { synchronized (AccountingSynchronized.class) { for (int i = 0; i < 1000000; i++) { j++; } } } public static void main(String[] args) throws InterruptedException { AccountingSynchronized instance = new AccountingSynchronized(); Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(j); } }