关于Syschronized的问题

新手上路,请多包涵

如下的代码,如果使用多线程调用的话。我知道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();
        }

    }
阅读 2.8k
3 个回答

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

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

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

synchronized(accounts) {
   ...
}

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

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题