线程同步的必要性

一、帐户类java

package com.ljb.app.synchronize;
/**
 * 模拟帐户类(线程同步必要性)
 * @author LJB
 * @version 2015年3月10日
 */
public class Account {
 // 余额
 private int balance = 500;
 
 // 查询余额
 public int getBalance() {
  return balance;
 }
 // 取款(这里没有设置余额判断<余额大于0,余额足够支付取款数量>)
 public void withdraw (int amount) {
  balance = balance - amount;
 }
}

二、取款线程(拥有同一个帐户)app

 package com.ljb.app.synchronize;
/**
 * 取款线程(模拟动态取款)
 * @author LJB
 * @version 2015年3月10日
 */
public class WithdrawThread implements Runnable{
 /*
  *  全部用此对象建立的线程共享同一个帐户
  */
 private Account account = new Account();
 
 /*
  *  取款、查询余额(non-Javadoc)
  * @see java.lang.Runnable#run()
  */
 public void run () {
  for (int i = 0 ; i < 5 ; i++) {
   // 取款
   makeWithdraw(100);
   
   // 查询余额
   if (account.getBalance() < 0) {
    System.out.println("帐户透支了!");
   }
  } 
 }
 
 /*
  * 取款 (余额不足给出提示)
  */
 private void makeWithdraw (int amount) {
  if (account.getBalance() >= amount) {
   System.out.println(Thread.currentThread().getName() + "准备取款。");
   
   try {
    Thread.sleep(500);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   
   // 0.5秒以后完成取款
   account.withdraw(amount);
   System.out.println(Thread.currentThread().getName() + "完成取款。");
  } else {
   System.out.println("余额不足以支付" 
        + Thread.currentThread().getName()
        + "的取款,余额为" + account.getBalance());
  }
 }
}

三、测试类测试

 package com.ljb.app.synchronize;
/**
 * 建立2个线程同时使用同一个帐户
 * @author LJB
 * @version 2015年3月10日
 */
public class TestWithdraw {
 /**
  * @param args
  */
 public static void main(String[] args) {
  // 建立实现Runnable接口类实例
  WithdrawThread withdraw = new WithdrawThread();
  
  // 建立2个线程
  Thread husband = new Thread(withdraw);
  Thread wife = new Thread(withdraw);
  
  husband.setName("丈夫");
  wife.setName("妻子");
  
  husband.start();
  wife.start();
 }
}

运行结果:spa

丈夫准备取款。
妻子准备取款。
妻子完成取款。
妻子准备取款。
丈夫完成取款。
丈夫准备取款。
妻子完成取款。
妻子准备取款。
丈夫完成取款。
丈夫准备取款。
妻子完成取款。
丈夫完成取款。
妻子准备取款。
丈夫准备取款。
丈夫完成取款。
帐户透支了!
妻子完成取款。
帐户透支了!
余额不足以支付妻子的取款,余额为-100
帐户透支了!
余额不足以支付丈夫的取款,余额为-100
帐户透支了!
四、同步方法
线程

/*
  * 取款 (余额不足给出提示)
  */
 private synchronized void makeWithdraw (int amount) {
  if (account.getBalance() >= amount) {
   System.out.println(Thread.currentThread().getName() + "准备取款。");
   
   try {
    Thread.sleep(500);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   
   // 0.5秒以后完成取款
   account.withdraw(amount);
   System.out.println(Thread.currentThread().getName() + "完成取款。");
  } else {
   System.out.println("余额不足以支付" 
        + Thread.currentThread().getName()
        + "的取款,余额为" + account.getBalance());
  }
 }

运行结果:code

丈夫准备取款。
丈夫完成取款。
妻子准备取款。
妻子完成取款。
妻子准备取款。
妻子完成取款。
妻子准备取款。
妻子完成取款。
丈夫准备取款。
丈夫完成取款。
余额不足以支付丈夫的取款,余额为0
余额不足以支付丈夫的取款,余额为0
余额不足以支付丈夫的取款,余额为0
余额不足以支付妻子的取款,余额为0
余额不足以支付妻子的取款,余额为0
对象

 五、同步代码块(比同步方法更强大)接口

/*
  * 取款 (余额不足给出提示)
  */
 private void makeWithdraw (int amount) {
  synchronized (account) {
   if (account.getBalance() >= amount) {
    System.out.println(Thread.currentThread().getName() + "准备取款。");
    
    try {
     Thread.sleep(500);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    
    // 0.5秒以后完成取款
    account.withdraw(amount);
    System.out.println(Thread.currentThread().getName() + "完成取款。");
   } else {
    System.out.println("余额不足以支付" 
         + Thread.currentThread().getName()
         + "的取款,余额为" + account.getBalance());
   }
  }
 }
相关文章
相关标签/搜索