一 、用synchronized()来实现线程的同步,书上一个银行存取款的例子很明确
public class Example12_7 {
public static void main(String args[]) {
Bank bank = new Bank();
bank.setMoney(200);
Thread accountant, //会计
cashier; //出纳
accountant = new Thread(bank);
cashier = new Thread(bank);
accountant.setName("会计");
cashier.setName("出纳");
accountant.start();
cashier.start();
}
}
package thread;
public class Bank implements Runnable {
int money=200;
public void setMoney(int n) {
money=n;
}
public void run() {
if(Thread.currentThread().getName().equals("会计"))
saveOrTake(300);
else if(Thread.currentThread().getName().equals("出纳"))
saveOrTake(150);;
}
public synchronized void saveOrTake(int amount) { //存取方法
if(Thread.currentThread().getName().equals("会计")) {
for(int i=1;i<=3;i++) {
money=money+amount/3; //每存入amount/3,稍歇一下
System.out.println(Thread.currentThread().getName()+
"存入"+amount/3+",帐上有"+money+"万,休息一会再存");
try { Thread.sleep(1000); //这时出纳仍不能使用saveOrTake方法
}
catch(InterruptedException e){}
}
}
else if(Thread.currentThread().getName().equals("出纳")) {
for(int i=1;i<=3;i++) { //出纳使用存取方法取出60
money=money-amount/3; //每取出amount/3,稍歇一下
System.out.println(Thread.currentThread().getName()+
"取出"+amount/3+"帐上有"+money+"万,休息一会再取");
try { Thread.sleep(1000); //这时会计仍不能使用saveOrTake方法
}
catch(InterruptedException e){}
}
}
}
}
二 、线程的协调同步
线程用wait()让出CPU使用权,待执行的程序完毕后调用nofity ()或notifyAll()来通知处于等待的线程结束等待并于断点处继续执行(notifyAll()是对全部,nofity ()是对个体)。
书上买电影票的例子我觉得很准却的描述了这个过程。
public class Example12_8 {
public static void main(String args[ ]) {
TicketHouse officer = new TicketHouse();
Thread zhangfei,likui;
zhangfei = new Thread(officer);
zhangfei.setName("张飞");
likui = new Thread(officer);
likui.setName("李逵");
zhangfei.start();
likui.start();
}
}
public class TicketHouse implements Runnable {
int fiveAmount=2,tenAmount=0,twentyAmount=0;
public void run() {
if(Thread.currentThread().getName().equals("张飞")) {
saleTicket(20);
}
else if(Thread.currentThread().getName().equals("李逵")) {
saleTicket(5);
}
}
private synchronized void saleTicket(int money) {
if(money==5) { //如果使用该方法的线程传递的参数是5,就不用等待
fiveAmount=fiveAmount+1;
System.out.println( "给"+Thread.currentThread().getName()+"入场卷,"+
Thread.currentThread().getName()+"的钱正好");
}
else if(money==20) {
while(fiveAmount<3) {
try { System.out.println("\n"+Thread.currentThread().getName()+"靠边等...");
wait(); //如果使用该方法的线程传递的参数是20须等待
System.out.println("\n"+Thread.currentThread().getName()+"继续买票");
}
catch(InterruptedException e){}
}
fiveAmount=fiveAmount-3;
twentyAmount=twentyAmount+1;
System.out.println("给"+Thread.currentThread().getName()+"入场卷,"+
Thread.currentThread().getName()+"给20,找赎15元");
}
notifyAll();
}
}