这些线程同步到哪个对象

时间:2014-03-31 11:02:35

标签: java multithreading monitor synchronized

我想同步通过ExecutorService调用的3个线程。如何确保它们在同一个对象上同步?

现在我有了这段代码:

class Test { 
    executor.submit(new Request(threadNames[i]));
    executor.submit(new Request(threadNames[i]));
    executor.submit(new Request(threadNames[i])); 

    private class Request implements Callable {
        @Override
        public Long call() throws InterruptedException {
            if (threadName.equals("SOMETHING") {
                doSomething();
            } else {
                doSomeOtherThing();
            }
        }
    }

    private synchronized void doSomething() {
    }

    private synchronized void doSomeOtherThing() {
    }

    ...
}

其中一个线程负责生成一个条件,另一个线程负责它。

2 个答案:

答案 0 :(得分:1)

  1. 您无法将线程提交给Executor服务;你提交 tasks ,稍后会在Executor的线程池中的一个线程上执行;

  2. 如果一个任务是生产者而另外两个是消费者,则将所有三个任务提交给执行者是错误的。它很容易导致死锁,消费者任务无限期地等待生产者,但生产者无法运行,因为消费者占据了所有线程。

  3. 重新考虑您的解决方案,以便生产者任务还负责将消费者任务提交给执行者;任务可以使用生成的值进行实例化,因此协调问题在一开始就得到了解决。

答案 1 :(得分:0)

根据文件(http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html):

  

每个对象都有一个与之关联的内在锁。按照惯例,   需要对对象进行独占和一致访问的线程   fields必须在访问之前获取对象的内部锁   它们,然后在它们完成时释放内在锁。一个   据说线程拥有它之间的内在锁定   获得了锁并释放了锁。

     

当线程调用synchronized方法时,它会自动获取   该方法的对象的内在锁定,并在该方法时释放它   方法返回。即使返回发生,也会发生锁定释放   一个未被捕获的例外。

     

您可能想知道静态同步方法会发生什么   调用,因为静态方法与类关联,而不是   宾语。在这种情况下,线程获取内部锁   与类关联的类对象。从而访问类的静态   字段由锁定控制,该锁定与任何锁定不同   班级的实例。

所以你的方法正在使用来自Test对象的内部锁定,是的,正如Marko正确指出的那样,你可能会陷入僵局。