線程安全:多個線程操做同一個共享資源的時候可能出現線程安全問題。java
/** 先模擬一個線程安全問題的案例:轉帳功能。 分析:整存整取。 (1)定義一個帳戶(餘額,卡號)。 (2)定義一個取錢的線程類 (3)建立一個帳戶對象,建立2個線程對象,去這個帳戶對象取錢10000 小結: 多個線程操做同一個共享資源的時候可能出現線程安全問題。 */ public class ThreadSave { public static void main(String[] args) { // 1.建立一個共享資源:是一個帳戶對象。這個對象必須只有一個。 Account acc = new Account("ICBC-110", 10000 ); // 2.建立2個線程對象表明小明和小紅 DrawThread xiaoMing = new DrawThread("小明",acc); xiaoMing.start(); DrawThread xiaoRed = new DrawThread("小紅",acc); xiaoRed.start(); } } /** 取錢的線程類。 */ public class DrawThread extends Thread { // 定義一個成員變量接收帳戶對象 private Account acc; public DrawThread(String name , Account acc){ super(name); this.acc = acc; } @Override public void run() { // 去帳戶acc中取錢 acc.drawMoney(10000); } } /** * 帳戶對象: */ public class Account { private String cardId ; private double money ; // 餘額 public Account() { } public Account(String cardId, double money) { this.cardId = cardId; this.money = money; } // 小明和小紅都到這裏來了 public void drawMoney(double money) { // 1.先拿到是誰來取錢:拿到當前線程的名字便可,名字是誰就是誰來取錢 String name = Thread.currentThread().getName(); // 2.判斷餘額是否足夠 if(this.money >= money){ // 錢夠了 System.out.println(name+"來取錢,餘額足夠,吐出:"+money); // 3.更新餘額 this.money -= money; System.out.println(name+"取錢後剩餘:"+this.money); }else{ // 錢不夠 System.out.println(name+"來取錢,餘額不足"); } } public String getCardId() { return cardId; } public void setCardId(String cardId) { this.cardId = cardId; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }
同步代碼塊安全
/** * 帳戶對象: */ public class Account { private String cardId ; private double money ; // 餘額 public Account() { } public Account(String cardId, double money) { this.cardId = cardId; this.money = money; } // 小明和小紅都到這裏來了 public void drawMoney(double money) { // 1.先拿到是誰來取錢:拿到當前線程的名字便可,名字是誰就是誰來取錢 String name = Thread.currentThread().getName(); // 2.判斷餘額是否足夠 : 和小紅 synchronized (this){ // this == acc //小明 if(this.money >= money){ // 錢夠了 System.out.println(name+"來取錢,餘額足夠,吐出:"+money); // 3.更新餘額 this.money -= money; System.out.println(name+"取錢後剩餘:"+this.money); }else{ // 錢不夠 System.out.println(name+"來取錢,餘額不足"); } } } public String getCardId() { return cardId; } public void setCardId(String cardId) { this.cardId = cardId; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }
同步方法ide
/** * 帳戶對象: */ public class Account { private String cardId ; private double money ; // 餘額 public Account() { } public Account(String cardId, double money) { this.cardId = cardId; this.money = money; } // 小明和小紅都到這裏來了 public synchronized void drawMoney(double money) { // 1.先拿到是誰來取錢:拿到當前線程的名字便可,名字是誰就是誰來取錢 String name = Thread.currentThread().getName(); // 2.判斷餘額是否足夠 : 和小紅 //小明 if(this.money >= money){ // 錢夠了 System.out.println(name+"來取錢,餘額足夠,吐出:"+money); // 3.更新餘額 this.money -= money; System.out.println(name+"取錢後剩餘:"+this.money); }else{ // 錢不夠 System.out.println(name+"來取錢,餘額不足"); } } public String getCardId() { return cardId; } public void setCardId(String cardId) { this.cardId = cardId; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }
同步鎖this
/** * 帳戶對象: */ public class Account { private String cardId ; private double money ; // 餘額 // 建立一把鎖對象:必須保證這個對象惟一 private final Lock lock = new ReentrantLock(); public Account() { } public Account(String cardId, double money) { this.cardId = cardId; this.money = money; } // 小明和小紅都到這裏來了 public void drawMoney(double money) { // 1.先拿到是誰來取錢:拿到當前線程的名字便可,名字是誰就是誰來取錢 String name = Thread.currentThread().getName(); // 2.判斷餘額是否足夠 : 和小紅 //小明 lock.lock(); try{ if(this.money >= money){ // 錢夠了 System.out.println(name+"來取錢,餘額足夠,吐出:"+money); // 3.更新餘額 this.money -= money; System.out.println(name+"取錢後剩餘:"+this.money); }else{ // 錢不夠 System.out.println(name+"來取錢,餘額不足"); } }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); // 解鎖操做! } } public String getCardId() { return cardId; } public void setCardId(String cardId) { this.cardId = cardId; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }