关于Syschronized的问题

发布于 2022-09-11 23:20:15 字数 847 浏览 30 评论 0

如下的代码,如果使用多线程调用的话。我知道syncTransfer的方法体同时只能有一个线程执行它。但是有没有可能另外一个线程在这个方法体执行的时候调用另外的方法修改了 accounts[from] 的值呢?

    public void syncTransfer(int from, int to, double amount) {
        lock.lock();
        try {
            while (accounts[from] < amount) {
                sufficientFunds.await();//满足条件钱不再向下执行同时释放锁。
            }
            System.out.print(Thread.currentThread());
            accounts[from] -= amount;
            System.out.println("从" + from + "转到" + to + "金额" + amount);
            accounts[to] += amount;
            System.out.println("当前银行一共金额" + getTotalBalance());
            sufficientFunds.signalAll(); //唤醒所有等待这个锁的线程
        } catch (Exception e) {
            System.err.println(e.getStackTrace());
        } finally {
            //必须释放锁
            lock.unlock();
        }

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

单挑你×的.吻 2022-09-18 23:20:15

你这好像是 lock 没用 syschronized 吧……

你的担忧是对的,所以严格上来说是给每个会被多线程读写的对象加锁,而不是纯的给方法加锁(方法加锁的目的也是为了给对象加锁)。

离笑几人歌 2022-09-18 23:20:15

从代码上看,给 accounts 加锁才是更合理的

synchronized(accounts) {
   ...
}
骄兵必败 2022-09-18 23:20:15

你这是lock不是synchronized吧。。。。。
原文的这个方法是线程安全的,同时只允许一个线程执行,但是对于accounts数组中某一个值是线程不安全的,存在多线程同时操作数据的情况。
我建议的做法是,将同步行为封装在对象的内部,使用lock或者synchronized在转账或者存款这些修改型的内部方法加锁,外部就不需要再额外关注线程安全的问题了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文