2016-01-26 133 views
0

我目前正在学习Java中的同步。据我了解,一个同步实例方法获取对象的锁。Java多线程共享同一对象的同步问题

我的程序是一个50个任务,然后每个给定一个线程。每个任务都将一分钱添加到由Account类创建的Account对象。

账户类有一个余额数据字段和一个同步存款方法。 50个任务具有指向相同账户对象(即共享账户)的账户字段。一旦运行被调用,每个任务将调用account.deposit实例方法来存入1个单元。

我希望余额以50个单位结尾。令人惊讶的是,账户最终有50个有时或其他余额14,48,33等。

class JavaStudy { 
    public static void main(String[] args){ 

     for (int j = 0; j < 10; j++) { 

      Account account = new Account(); 

      ExecutorService executorPool = Executors.newFixedThreadPool(50); 

      for (int i = 0; i < 50; i++) { 
       executorPool.execute(new DepositTask(account)); 
      } 

      executorPool.shutdown(); 

      while(!executorPool.isShutdown()){ 
      } 

      System.out.println(account.getBalance()); 
     } 
    } 
} 

存款任务类!

class DepositTask implements Runnable { 

    private Account account; 

    DepositTask(Account account){ 
     this.account = account; 
    } 

    @Override 
    public void run() { 
     account.deposit(1); 
    } 
} 

账户类别!根据我所理解的,据我所知,当任务访问account.deposit(1)时,帐户应该被锁定;然后, 。其他任务应该无法访问它,因为它们共享相同的对象!不知何故,这是不会的,我结束了下面的结果,

Balance: 20 
Balance: 47 
Balance: 50 
Balance: 42 
Balance: 27 
Balance: 24 
Balance: 50 
Balance: 29 
Balance: 13 
Balance: 12 

Process finished with exit code 0 

对发生了什么事情的任何想法?

+1

简化这个 “而{}(executorPool.isShutdown()!)” - 有阻塞的方法来实现等待终止!请不要这样做! – Fildor

回答

5

我怀疑你不是在等待与关机不同的终止。这可能意味着并非所有任务都已完成。

executorPool.shutdown(); 
executorPool.awaitTermination(1, TimeUnit.MINUTES); 
System.out.println(account.getBalance()); 

BTW在Java 8,你可以用

Account account = new Account(); 

InStream.range(0, 50).parallel() 
        .forEach(i -> account.deposit(1)); 

System.out.println(account.getBalance()); 
+0

@OldCurmudgeon感谢您的更正。 –

+1

谢谢!这解决了问题!关机可防止执行器池接受进一步的任务,但正在处理的任务仍在运行!那就是为什么,就像你说的那样,这个平衡显示出了不连贯的价值! –