线程同步实现银行取款关键步骤:
同步方法
同步代码块
同步实现的必要性:有一些同时运行的线程需要共享数据,此时就需要考虑其他线程的状态和行为,否则就会影响程序的正常运行。
线程同步:当两个或多个线程需要访问统一资源时,需要以某种顺序来确保该资源在某一时刻只能被一个线程使用。
线程同步的方法:同步方法和同步代码块。
同步方法:通过在方法声明中加入synchronized关键字来声明同步方法。但如果一个方法运行时间太长会影响运行效率。
同步代码块:对需要控制的代码块进行同步控制,较同步方法较高效,但由于一些额外的人为因素,容易出现错误。
同步代码块格式:
synchronized(syncObject){
//需要同步访问控制的代码。
}
同步实现银行取钱
定义银行账户类;
/**
*
*/
package zut.edu.cs.network.practice;
/**
* @author Administrator
*
*/
public class Account {
private int balance=500;
/**
* @return the balance
*/
public int getBalance() {
return balance;
}
//withdraw the money
public void withdraw(int amount) {
balance=balance-amount;
}
}
取款的线程类
/**
*
*/
package zut.edu.cs.network.practice;
/**
* @author Administrator
*
*/
public class TestAccount implements Runnable {
private Account a=new Account();
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<5;i++) {
makeWithdrawal(100);
if(a.getBalance()<0) {
System.out.println("no money!");
}
}
}
/**
* @param i
*/
public synchronized void makeWithdrawal(int i) {
// TODO Auto-generated method stub
if(a.getBalance()>=i) {
System.out.println("ready to withdraw the money:");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//余额足够取款
a.withdraw(i);
System.out.println("withdraw the money successfully!");
}
//余额不足给出提示
else {
System.out.println("no money to draw for"+Thread.currentThread().getName()+" and the balance of "+a.getBalance());
}
}
}
测试类
/**
*
*/
package zut.edu.cs.network.practice;
import junit.framework.Test;
/**
* @author Administrator
*
*/
public class TestWithdraw {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TestAccount t=new TestAccount();
Thread one =new Thread(t);
Thread two =new Thread(t);
one.setName("Zhangsan");
two.setName("Zhangsan'wife");
//start thread
one.start();
two.start();
}
}
不用同步 运行截图
同步后 程序 运行截图