当多个线程,访问同一个对象,调用同一个方法或访问同一个对象时。有时,必须保证访问的同步性。
比如,一个银行信用卡账户具有5000元的信用额度。用户除具有一张主卡外,还办有多张子卡。这些卡的累计消费金额,不能超过信用卡的额度。当用户在多个POS机上请求消费时,如果不对请求操作进行操作,可能会造成错误。
/**
* 同步模拟银行信用卡取款
*/
public class Tongbu implements Runnable{
private int money;
private int get;
public int getMoney() {
return money;
}
public void setGet(int get) {
this.get = get;
}
public Tongbu(){
this.money = 5000;
}
public synchronized void get() {
if (this.money >= get) {
/*此处休眠,以摸拟,假使在此时,多个请求线程之间进行了切换。一个线程让出处理器。*/
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
this.money -= get;
System.out.println("取款成功。" + get);
} else {
System.out.println("余额不足。");
}
}
@Override
public void run() {
if (get>0) get();
}
public static void main(String[] args){
Tongbu t1=new Tongbu();
Thread T=new Thread(t1);
Thread T1=new Thread(t1);
t1.setGet(3000);
T.start();
t1.setGet(3000);
T1.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("余额: "+t1.getMoney());
}
}
以上例子若是t1取款3000,t1再取款2000就会两次都取款2000,第一次取的3000就少了1000.这是因为get是共享的,会覆盖。
以下是改进例子:
**
* 同步模拟银行信用卡取款
*/
public class Tongbu extends Thread{
private creditCard card;
private Integer get;
public Integer getGet() {
return get;
}
public void setGet(Integer get) {
this.get = get;
}
public Tongbu(creditCard card){
this.card = card;
}
public void get() {
if ( card.getMoney()>= get) {
/*此处休眠,以摸拟,假使在此时,多个请求线程之间进行了切换。一个线程让出处理器。*/
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
card.setMoney(card.getMoney()-get);
System.out.println("取款成功。" + get);
} else {
System.out.println("余额不足。");
}
}
@Override
public void run() {
if (get>0) get();
}
public static void main(String[] args){
creditCard card=new creditCard(5000);
Tongbu t1=new Tongbu(card);
Tongbu t2=new Tongbu(card);
t1.setGet(3000);
t1.start();
System.out.println("余额: "+card.getMoney());
t2.setGet(1000);
t2.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("余额: "+card.getMoney());
}
}
class creditCard{
private int money;
public creditCard(int money) {
this.money = money;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}