线程互斥就是用关键字synchronized 来对共享数据对象尽心锁定, 包括synchronized方法和 synchronized 块
看一个经典的银行例子代码:
import java.io.*;
class hello //银行账户类, 名字不好听
{
private String holdName;
private double amount;
public hello(String holdName){
this.holdName = holdName;
this.amount = 0;
System.out.println("新开一个账户 : " + this.holdName);
}
public synchronized void deposit(double amt){ //存款, 锁定这个方法
this.amount += amt;
System.out.println(this.holdName + " 存入" + amt);
}
public synchronized void withdrow(double amt){ //取款, 锁定这个方法
if(amt > this.amount){
System.out.println(this.holdName + "想取出" + amt + ", 但是余额不足, 实际" + " 取出" + this.amount);
amt = this.amount;
this.amount -= amt;
}
else{
System.out.println(this.holdName + " 取出" + amt);
this.amount -= amt;
}
}
public synchronized double checkBalance(){ //查询, 锁定这个方法
return this.amount;
}
public static void main(String args[])
{
hello h = new hello("罗同龙");
(new Save(h, 100)).start();
(new Save(h, 200)).start();
(new Save(h, 300)).start();
(new Fetch(h, 200.0)).start();
}
}
class Save extends Thread //存款的线程
{
private hello a1;
private double amount;
public Save(hello a, double amt){
this.a1 = a;
this.amount = amt;
}
public void run(){
synchronized (a1){ ///当或得对象A1的锁后就锁定这个代码块
double k = a1.checkBalance();
try{
sleep(1);
}catch(InterruptedException e){
System.out.println(e);
}
a1.deposit(this.amount);
System.out.println("剩余 :" + a1.checkBalance() );
}
}
}
class Fetch extends Thread //取钱线程
{
private hello a1;
private double amount;
public Fetch(hello a, double amt){
this.a1 = a;
this.amount = amt;
}
public void run(){
synchronized (a1){ //当或得对象A1的锁后就锁定这个代码块
double k = a1.checkBalance();
try{
sleep(1);
}
catch(InterruptedException e){
System.out.println(e);
}
a1.withdrow(amount);
System.out.println("剩余 :" + a1.checkBalance() );
}
}
}
每次运行结果不尽相同:
新开一个账户 : 罗同龙
罗同龙 存入100.0
剩余 :100.0
罗同龙想取出200.0, 但是余额不足, 实际 取出100.0
剩余 :0.0
罗同龙 存入300.0
剩余 :300.0
罗同龙 存入200.0
剩余 :500.0