java多執行緒之同步鎖
阿新 • • 發佈:2021-01-03
技術標籤:javasynchronized同步
本篇是多執行緒不安全例項,模擬的是兩人取錢的過程,若兩人同時取100,會造成餘額為負的結果,說明多執行緒存在安全問題。
首先是不安全的例項。
package lesson04; public class TestBank { public static void main(String[] args) { Account account = new Account("結婚基金", 100); DrawingMoney you = new DrawingMoney(50,0,account); DrawingMoney wife = new DrawingMoney(100,0,account); new Thread(you).start(); new Thread(wife).start(); } } //賬戶 class Account { String name;//卡名 int money;//卡內餘額 //有參構造 public Account(String name,int money) { this.name = name; this.money = money; } } //銀行取錢,模擬多執行緒 class DrawingMoney implements Runnable { int drawingMoney ; int haveMoney; Account account; //構造器 public DrawingMoney(int drawingMoney, int haveMoney, Account account) { this.drawingMoney = drawingMoney; this.haveMoney = haveMoney; this.account = account; } @Override public void run() { if (account.money - drawingMoney <= 0 ) { System.out.println("卡里餘額不足"); return; } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } account.money = account.money-drawingMoney; haveMoney = haveMoney+drawingMoney; System.out.println(Thread.currentThread().getName()+"手裡有"+haveMoney); System.out.println(account.name+"卡餘額為"+account.money); } }
執行結果:
這裡就引入了synchronized同步機制,使用鎖加佇列的方式確保了多執行緒操作的安全。這裡包括兩種:
1、synchronized方法:同步方法:publicsynchronized void method(args){};
2、synchronized方法體:synchronized(Obj){}
Obj稱之為同步監視器,可以是任何物件,同步方法中無需指定同步監視器,因為同步方法的監視器就是this,這個物件的本身,或者是classl類
下面使用synchronized方法體對程式碼進行改造,使執行緒安全。
package lesson04; public class TestBank { public static void main(String[] args) { Account account = new Account("結婚基金", 100); DrawingMoney you = new DrawingMoney(50,0,account); DrawingMoney wife = new DrawingMoney(100,0,account); new Thread(you).start(); new Thread(wife).start(); } } //賬戶 class Account { String name;//卡名 int money;//卡內餘額 //有參構造 public Account(String name,int money) { this.name = name; this.money = money; } } //銀行取錢,模擬多執行緒 class DrawingMoney implements Runnable { int drawingMoney ; int haveMoney; Account account; //構造器 public DrawingMoney(int drawingMoney, int haveMoney, Account account) { this.drawingMoney = drawingMoney; this.haveMoney = haveMoney; this.account = account; } //取錢 //synchronized預設鎖的是this @Override public void run() { //鎖的物件就是變化的量,增刪改的物件 synchronized (account){ if (account.money - drawingMoney <= 0 ) { System.out.println("卡里餘額不足"); return; } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } account.money = account.money-drawingMoney; haveMoney = haveMoney+drawingMoney; System.out.println(Thread.currentThread().getName()+"手裡有"+haveMoney); System.out.println(account.name+"卡餘額為"+account.money); } } }
執行結果: