2015-10-16 63 views
0

我想在几个线程(6)之间同步一个int计数器。以下是我的工人班。我想我的私人领域countertest同步:Java在执行程序服务池中的线程之间同步数据

public class DbWorker implements Callable { 

    private final Object lock = new Object(); 
    private int countertest = 0 ; 

    private boolean IsActive(Integer act) 
    { 
     synchronized(lock){ 
     boolean exists = false; 
     countertest++; 
      .... 
     System.out.println("countertest IS : " + countertest); 
     } 
     return true; 
    } 

    public void run() { 
     .... 
     IsActive(act): 
     ... 
    } 

} 

在我的主类我使用for循环和ExecutorService的创建线程。请看下面:

private ExecutorCompletionService<Integer> _objQueue ; 

for(int j = 0; j < 6; j++){ 
    _objQueue.submit(new DbWorker("SOME PARAMETER" , _snapshots.get(j) , j) ); 
} 

我countertest变量没有同步它打印不同的数字(非顺序)。我究竟做错了什么?

+0

“重复”,国际海事组织,是一个坏的问题,一个不好的答案。不好的,因为它促进了对象可以是“静态”或不静态的想法。 (他们不能:只有_variables_可以是静态的或不是静态的。)而且,不好的,因为它促进了'静态'在锁定方面的不同。 (事实并非如此,重要的是,两个线程不能同时锁定同一个对象,'synchronized'语句是从静态变量,非静态变量还是通过调用方法获取引用是不相关)。 –

回答

3

你锁

private final Object lock = new Object(); 

是一个实例字段。换句话说,每个DbWorker对象都有一个。

你然后提交DbWorker实例来执行

_objQueue.submit(new DbWorker("SOME PARAMETER" , _snapshots.get(j) , j) ); 

每个线程都有自己的DbWorker,因此自己的锁。线程永远不会与任何其他线程竞争。

创建一个DbWorker并在线程中共享它,即。 submit每次都一样DbWorker实例。

+0

我正在为每个DbWorker传递一个参数。我不能使用相同的DbWorker。 –

+0

@KennerDev然后分享计数器和它们之间的锁。如果有的话,使用“AtomicInteger”。 –

+0

我的锁已经是最终的了,我还需要做什么? –

2

因为您在循环中创建一个实例,其中countertestlock是实例变量,因此每个对象都会得到一个新实例。

  1. countertest将始终是1在这种情况下,它不是实例

  2. 多个线程不获取相同的锁,所以它是无用之间共享。

+0

我正在为每个DbWorker传递一个参数。我不能使用相同的DbWorker。 –

+0

我只是回答你的问题,“为什么它不工作”。我不知道你想做什么,但是你的代码看起来很破碎 –