用多线程的方法来描述如下的银行业务:丈夫和妻子共同用于一个账户,账户上的资金为10000元,丈夫(每次3000)不停的存钱。妻子(每次1500)不停的从上面的账户上取钱。每次存/取钱的时间均为1秒。
***********Account.java*************
public class Account {
private int myAccount = 10000;
public int getMyAccount(){
return myAccount;
}
public void setMyAccount(int myAccount) {
this.myAccount = myAccount;
}
}
***********Husband.java*************
public class Husband extends Thread{
    private Account myAccount;
    public Husband(Account myAccount){
this.myAccount = myAccount;
    }
    public void run(){
while(true){   
int temp = 0;
try {
Thread.sleep(300);
temp = myAccount.getMyAccount() +3000;
Thread.sleep(1000);
myAccount.setMyAccount(temp);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("丈夫:"+myAccount.getMyAccount());
}
    }
}
***********wife.java*************
public class wife extends Thread{
    private Account myAccount;
    public wife(Account myAccount){
this.myAccount = myAccount;
    }
    public void run(){
while(true)
{   
int temp = 0;
try {
temp = myAccount.getMyAccount() - 1500;
Thread.sleep(1000);
myAccount.setMyAccount(temp);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("妻子:"+myAccount.getMyAccount());
}
    }
}
***********Test.java*************
public class Test {
public static void main(String[] args) {
Account finalAccount = new Account();
Husband Husband = new Husband(finalAccount);
wife wife = new wife(finalAccount);
Husband.start();
wife.start();
}
}
大家看一下输出结果,分明两个共享的是一个帐户,而输出结果看起来确是两个帐户呢?为什么会出现这样的问题?如何解决?

解决方案 »

  1.   

    把Husband.java的run()方法中的Thread.sleep(300);去掉,刚才做测试忘删了
      

  2.   

    ***********Account.java*************
    public class Account {
    private int myAccount = 10000;
    public int getMyAccount(){
    return myAccount;
    }
    public void setMyAccount(int myAccount) {
    this.myAccount = myAccount;
    }
    }
    ***********Husband.java*************
    public class Husband extends Thread{
        private Account myAccount;
        public Husband(Account myAccount){
    this.myAccount = myAccount;
        }
        public void run(){
    while(true){   
    int temp = 0;
    try {
    temp = myAccount.getMyAccount() +3000;myAccount.setMyAccount(temp);System.out.println("丈夫:"+myAccount.getMyAccount());
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
        }
    }
    ***********wife.java*************
    public class wife extends Thread{
        private Account myAccount;
        public wife(Account myAccount){
    this.myAccount = myAccount;
        }
        public void run(){
    while(true)
    {   
    int temp = 0;
    try {
    temp = myAccount.getMyAccount() - 1500;myAccount.setMyAccount(temp);System.out.println("妻子:"+myAccount.getMyAccount());
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
        }
    }
    ***********Test.java*************
    public class Test {
    public static void main(String[] args) {
    Account finalAccount = new Account();
    Husband Husband = new Husband(finalAccount);
    wife wife = new wife(finalAccount);
    Husband.start();
    wife.start();
    }
    }
    这样应该就可以了
      

  3.   

    先Thread.sleep(1000);
    再System.out.println("妻子:"+myAccount.getMyAccount()); 中途有时间差
     husband可能修改了 帐户里面的金额
      

  4.   

    我觉得是这样的啊,里面有修改account的方法,所以会改变
      

  5.   

    使用多线程,以下方法不做成同步是会有问题的.
    public void setMyAccount(int myAccount) {
    this.myAccount = myAccount;
    }
    因为两个线程都会使用这个方法,对全局变量进行修改,这样是不安全的。
    公用对象的对全局变量修改的方法要做成同步的,这是使用多线程最基本的原则。public void synchronized setMyAccount(int myAccount) {
    this.myAccount = myAccount;
    }
      

  6.   

    这样的问题要做同步处理:
    1,互斥访问共享变量,这里是帐户
    2,需要同步丈夫和妻子,要考虑丈夫存的钱不够妻子花(哈哈,经常的事情),丈夫存的钱妻子花不完(留点自己用嘛)
    //
    你的程序问题很多啦,我就不一一指啊,我列下我写的,现在没环境没调试,不过应该没多大问题:改进一:
    ***********Account.java*************
    public class Account {
    private int myAccount = 10000;
    public synchronized int getMyAccount(){
    return myAccount;
    }
    public synchronized void setMyAccount(int myAccount) {
    this.myAccount += myAccount;
    }
    }
    ***********Husband.java*************
    public class Husband extends Thread{
        private Account myAccount;
        public Husband(Account myAccount){
    this.myAccount = myAccount;
        }
        public void run(){
    while(true){   
    int temp = 0;
    try {
    Thread.sleep(300);
    //temp = myAccount.getMyAccount() +3000;
    //Thread.sleep(1000);
    //myAccount.setMyAccount(temp);
    myAccount.setMyAccount(3000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("丈夫:"+myAccount.getMyAccount());
    }
        }
    }
    ***********wife.java*************
    public class wife extends Thread{
        private Account myAccount;
        public wife(Account myAccount){
    this.myAccount = myAccount;
        }
        public void run(){
    while(true)
    {   
    int temp = 0;
    try {
    //temp = myAccount.getMyAccount() - 1500;
    Thread.sleep(1000);
    //myAccount.setMyAccount(temp);
    myAccount.setMyAccount(-1500);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("妻子:"+myAccount.getMyAccount());
    }
        }
    }改进二:
    ***********Account.java*************
    public class Account {
    private int myAccount = 10000;
    public synchronized int getMyAccount(){
    return myAccount;
    } //public synchronized void setMyAccount(int myAccount) {
    // this.myAccount += myAccount;
    //}

    public synchronized void storeAccount(int count){
    while(myAccount>100000){
    //钱多了,留些自己用
    notifyAll();
    try{
    wait();
    }catch(InterruptedException e){}
    }
    myAccount+=count;
    notifyAll();
    }
    public synchronized int getAccount(int count){
    while(myAccount<count){
    //钱不够了,存点钱给妻子用啊
    notifyAll();
    try{
    wait();
    }catch(InterruptedException e){}
    myAccount-=count;
    notifyAll();
    return count;
    }
    }
    ***********Husband.java*************
    public class Husband extends Thread{
        private Account myAccount;
        public Husband(Account myAccount){
    this.myAccount = myAccount;
        }
        public void run(){
    while(true){   
    int temp = 0;
    try {
    Thread.sleep(300);
    //temp = myAccount.getMyAccount() +3000;
    //Thread.sleep(1000);
    //myAccount.setMyAccount(temp);
    myAccount.setMyAccount(3000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("丈夫:"+myAccount.getMyAccount());
    }
        }
    }
    ***********wife.java*************
    public class wife extends Thread{
        private Account myAccount;
        public wife(Account myAccount){
    this.myAccount = myAccount;
        }
        public void run(){
    while(true)
    {   
    int temp = 0;
    try {
    //temp = myAccount.getMyAccount() - 1500;
    Thread.sleep(1000);
    //myAccount.setMyAccount(temp);
    myAccount.setMyAccount(-1500);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("妻子:"+myAccount.getMyAccount());
    }
        }
    }//笔记本键盘可能有问题,飘了好几次可能有笔误  :(