关于Java多线程

今天java群里一个网友问了一个多线程的问题,代码我简化一下如下BankCard.java

public class BankCard {private int num;

public int getNum() {return num;}

public void setNum(int num) {this.num = num;}}

Father.java

public class Father implements Runnable {

private BankCard bc;private int temp;

public Father(BankCard bc) {this.bc = bc;}

public void run() {

temp = bc.getNum();

while (true) {

synchronized (bc) {if (temp <= 5000) {temp = bc.getNum();System.out.println(temp + “………..”);temp += 1500;bc.setNum(temp);System.out.println(“父親放進了1500,现在剩余+” + temp);} elseThread.yield();

}

}

}}GrandFather.java

public class GrandFather implements Runnable {

private int temp ;private BankCard bc;public GrandFather(BankCard bc){this.bc = bc;}public void run() {temp = bc.getNum();

while(true){

synchronized (bc) {

if (temp <= 5000) {temp = bc.getNum();temp += 800;bc.setNum(temp);System.out.println(“爺爺放進了800钱,现在剩余+”+temp);}elseThread.yield();}}

}

}Mother.java

public class Mother implements Runnable {

private int temp;

private BankCard bc;public Mother(BankCard bc){this.bc = bc;}

public void run() {temp = bc.getNum();while (true) {

synchronized (bc) {if (temp <= 5000) {temp = bc.getNum();temp += 1200;bc.setNum(temp);System.out.println(“母親存近了1200,现在剩余+”+temp);}elseThread.yield();}}

}

}Test.javapublic class Test {public static void main(String args[]){BankCard bc = new BankCard();Father ft = new Father(bc);Mother mt = new Mother(bc);GrandFather gft = new GrandFather(bc);Thread thread = new Thread(ft);thread.start();Thread thread1 = new Thread(mt);thread1.start();Thread thread2= new Thread(gft);thread2.start();}}那么这个程序的意思就是父亲,母亲,祖父,都可以向银行卡里存钱,如果超过了5000就不能再存

那么我们看结果

问题出现了,父亲最后存完钱钱已经超出5000了,虚拟主机,为6000元,为什么爷爷和母亲都还能存呢?

为了解决这个问题,我们在run方法下的第一个temp = bc.getNum();语句前后分别加上

System.out.println(“看看祖父怎么回事”);temp = bc.getNum();

System.out.println(“看看祖父怎么回事”+temp);三个文件分别换成对应名字

再看结果,因为多线程每次运行结果不同,我们以接下来的结果说明

程序刚开始执行,三个线程执行run方法,然后系统将执行权交给父亲线程

然后父亲执行三次循环,香港服务器租用,系统将执行权交给祖父线程,祖父线程执行到System.out.println(“看看祖父怎么回事”+temp);这一句时将执行权交给母亲线程,母亲线程同样执行一次循环,存入1200,现在卡上有5700,按道理来讲剩下的人不能再存了,但如图所示,爷爷和父亲又都各自存了一次,美国服务器,为什么呢?

因为在父亲交换执行权的时候父亲线程的temp值已经变为4500

然后祖父交换执行权的时候祖父线程的temp值同样为4500

而母亲执行完后仅仅是母亲线程的temp变为4500,而另外两个线程的temp值还都为4500

所以他们2个各自都还能再循环一次,故出现了这种情况

那么解决办法就是将run方法下的第一个temp = bc.getNum();语句放进synchronized 之中,if循环体之外,保证当前线程获得同步监视器锁定时再重新读取金钱数目,或者if(temp <= 5000)条件变为bc.getNum()<=5000,就避免了这种看似同步实际不同步的问题

本文出自 “学海无涯” 博客,请务必保留此出处

不要惧怕黑暗,人间没有永恒的夜晚;不要担心严寒,

关于Java多线程

相关文章:

你感兴趣的文章:

标签云: