一道面试题,好像是这样的
public class Account { int balance = 100; synchronized void draw(int num) {
this.balance = balance - num;
} void other(int num) {
draw(-num);
} public void test(Account from, Account to, int num) {
from.draw(num);
to.other(num);
}}并发下会出现什么问题,问题出现在哪一步

解决方案 »

  1.   

    void other(int num) {
    draw(-num);
    }
      

  2.   

    我觉得是这里
    this.balance = balance - num;
      

  3.   

    首先:int balance = 100;balance 访问会出现问题.
      

  4.   

    怎么不在draw方法里加锁呢,不要用synchronized ,以后在并发编程那书上看过使用synchronized不好,
    现在也不记得怎么不好了,所以我一直都用lock。
         
    l.lock();
         try {
             this.balance = balance - num;
         } finally {
             l.unlock();
         }
      

  5.   


    大哥!问题不在这里啊!lock();加这里还是有问题
      

  6.   

    用lock是可以使粒度最小化。
    我觉得应该是other这方法里的num变量,因为就它没有同步。。
      

  7.   

    应该没问题,对balance的操作已经同步了呀。只是test这个方法写在这里是有问题的。
      

  8.   

    banlance 应是volatile型,否则在优化时会有线程在寄存器中存有它的拷贝,导致数据不一致
      

  9.   

    这个貌似没什么问题吧,有问题吗? 进入同步块的线程也是能够有效保证块内所有变量的拷贝与主存的同步的存和取其实是一种动作,只是一个取正数一个取负数而已,取的动作已经同步,也进行了一些试验,多线程在同一个对象上不停draw,结果是一致的test方法内draw和other不应该在不同对象上试验吗?
      

  10.   

    应该没问题呀,线程安全包括 变量安全跟线程同步问题..
    首先 public void test(Account from, Account to, int num)  接收进来的from跟to是不同对象.内部的balance肯定不存在变量安全问题.
    然后调用的void draw(int num)又加了同步锁,真看不出有什么问题.楼主,如果你当时说,没问题.估计他们老板就要你了,我也是猜的,哈哈哈,等高手来看
      

  11.   

    no problem! different objects run with their own member variables!
      

  12.   

    很明显下面有问题:public void test(Account from, Account to, int num) {
       from.draw(num);
       to.other(num);
    }
    如果from帐号没有足够的钱,还是会转去to帐号。明显没有对嘛。如果有多个线程同时运行,就更明显了。
    可能from帐号被扣掉了1000,to帐号还没有到帐。也就是说,转账的操作,需要对两个帐号进行同步操作。
      

  13.   

    楼主没说不同对象中的balance是不是独立的呀.如果是有关系的,那23楼正解
      

  14.   

    and even if they are the same object they will be assured of synchronized state on both operation right
      

  15.   

    不会有问题:
    public void test(Account from, Account to, int num) {
    from.draw(num);
    to.other(num);
    }其中的参数据Account from和Account to 是二个不同的对象,它们都只操作了自己的方法。
      

  16.   

    void other(int num) {
    draw(-num);
    }