1)使用wait()、notify()和notifyAll()三个方法,来控制线程之间的调度。
2)上述三个方法属于Object类,必须由同步监视器来调用。
3)三种方法的解释:
a,wait(),导致当前线程等待,直到其他线程调用该同步监视器的notify()方法或者notifyAll()方法来唤醒该线程。
b,notify(),唤醒在此同步监视器上等待的单个线程,如果所有的线程都在此同步监视器上等待,则会选择唤醒其中一个,只有当前线程放弃锁定后,才可以执行被唤醒的线程;
c,notifyAll(),唤醒在此同步监视器上等待的所有线程。只有当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程。
4)源码示例
//Account.java代码
- package com.wayne.practice;
- public class Account {
- private String accountNo;
- private double balance;
-
- //设置是否账户中是否有钱的标志
- private boolean bFlagHasMoney = false;
-
- public Account(){}
- public Account(String accountNo, double balance) {
- super();
- this.accountNo = accountNo;
- this.balance = balance;
- }
- public String getAccountNo() {
- return accountNo;
- }
- public void setAccountNo(String accountNo) {
- this.accountNo = accountNo;
- }
- public double getBalance() {
- return balance;
- }
- @Override
- public int hashCode() {
- return accountNo.hashCode();
- }
- @Override
- public boolean equals(Object obj) {
- if(this == obj)
- return true;
-
- if((obj != null)&&(obj.getClass() == Account.class))
- {
- Account account = (Account)obj;
- if(this.getAccountNo().equals(account.getAccountNo()))
- return true;
- }
-
- return false;
- }
-
- //定义取钱的动作
- public synchronized void draw(double drawMoney)
- {
- if(!bFlagHasMoney)
- {
- try {
- wait();//如果bFlagHasMoney为假,则表示账户中没有钱,阻塞该取钱
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- else
- {
- System.out.println(Thread.currentThread().getName()+
- " 取款:"+drawMoney+"元!");
- this.balance-=drawMoney;
- System.out.println("账户余额为:"+this.getBalance());
- bFlagHasMoney = false;
- notifyAll();
- }
- }
-
- //定义存钱动作
- public synchronized void deposit(double depositMoney)
- {
- if(bFlagHasMoney)
- {
- try {
- wait();////如果bFlagHasMoney为真,则表示账户中有钱,阻塞其他用户存钱
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- else
- {
- System.out.println(Thread.currentThread().getName()+
- " 存款:"+depositMoney+"元");
- this.balance += depositMoney;
- System.out.println("账户余额为:"+this.getBalance());
- bFlagHasMoney = true;
- notifyAll();
- }
- }
-
- }
复制代码
//DepositMoneyThread.java代码
- package com.wayne.practice;
- //定义取钱的线程
- public class DepositMoneyThread extends Thread {
-
- private Account account;
- private double depositMoney;
- public DepositMoneyThread(){}
-
- public DepositMoneyThread(String thrName,Account account,double depositMoney)
- {
- super(thrName);
- this.account = account;
- this.depositMoney = depositMoney;
- }
-
- @Override
- public void run() {
- // TODO Auto-generated method stub
- for(int i = 0;i<10;i++)
- account.deposit(depositMoney);;
- }
-
- }
复制代码
//DrawMoneyThread.java代码
- package com.wayne.practice;
- //定义取钱的线程
- public class DrawMoneyThread extends Thread {
-
- private Account account;
- private double drawMoney;
- public DrawMoneyThread(){}
-
- public DrawMoneyThread(String thrName,Account account,double drawMoney)
- {
- super(thrName);
- this.account = account;
- this.drawMoney = drawMoney;
- }
-
- @Override
- public void run() {
- // TODO Auto-generated method stub
- for(int i = 0;i<10;i++)
- account.draw(drawMoney);
- }
-
- }
复制代码
//AccountAppk.java代码
package com.wayne.practice;
public class AccountApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
Account acct = new Account("123456",0);
new DrawMoneyThread("取款者", acct, 800).start();
new DepositMoneyThread("存款者甲", acct, 800).start();
new DepositMoneyThread("存款者乙", acct, 800).start();
new DepositMoneyThread("存款者丙", acct, 800).start();
}
}
|
|