线程安全:多个线程操做同一个共享资源的时候可能出现线程安全问题。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; } }