【问题标题】:How does this multithreaded Java code work?这个多线程 Java 代码是如何工作的?
【发布时间】:2012-05-12 06:49:43
【问题描述】:

鉴于此 Java 代码:

class Account {
        private Integer number = 0;
        public synchronized void setNumber(Integer number) {
            this.number = number;
        }

         public synchronized Integer getNumber() {
            return number;
        }
    }

    class Client extends Thread {
        Account account;
        public Client(Account account) {
            this.account = account;
        }
        public  void run() {
            for (int i = 1; i <= 1000; i++) {
            account.setNumber(account.getNumber() + 1);
             }
        }
    }

    public class Run {
        public static void main(String[] args) throws Exception {
            Account account = new Account();
            Client one = new Client(account);
            Client two = new Client(account);
            one.start();
            two.start();
            one.join();
            two.join();
           System.out.println("Exiting main");
       System.out.println("account number value: " +account.getNumber());        
        }
    }

main方法完成时number的值是多少?是2000还是2000以下?我得到的少于 2000。两个线程如何同时从 run() 调用 getNumer()setNumber(),因为每个线程都是同步的?

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    仔细思考下一节会发生什么。

    account.setNumber(account.getNumber() + 1);
    

    尽管这两种方法是分别同步的,但整个操作却不是。

    【讨论】:

    • 不客气。如果您的问题有答案,您应该选择正确答案之一。
    【解决方案2】:

    这个数字可能小于或等于 2000,但永远不会更高。考虑每个“set”和“get”数字函数单独同步,但它们没有一起同步。这意味着线程之间的竞争条件可能会“跳过”对组合“增量”效果的调用。

    考虑两个线程之间可能的调用序列:

    number  Thread1     Thread2
    0       get => 0    -
    -       -           get => 0
    -       -           incr => 1
    1       -           set => 1
    -       incr => 1   -
    1       set => 1    -
    

    请注意,每个线程都获得数字零,分别递增,然后设置数字一。两个线程都认为他们增加了数字,但他们对 set/get 的调用是交错的,因此其中一个被有效地跳过了。

    相比之下,请尝试在名为 increment() 的 Account 类中编写第三个同步方法,它以原子方式执行 get/increment/set 序列,并看到您将始终获得数字 2000。

    【讨论】:

    • 感谢 Maerics 回答我的问题
    猜你喜欢
    • 2015-06-17
    • 1970-01-01
    • 2010-12-13
    • 2013-04-23
    • 2015-04-09
    • 2013-07-24
    • 2014-03-26
    • 2012-11-14
    • 1970-01-01
    相关资源
    最近更新 更多