java中的同步锁

时间:2014-05-13 08:52:09

标签: java multithreading

我有多线程应用程序(例如,servlet)。我也有一个共同点  资源(文件,参考或其他)。如何同步其访问权限?这就是我的方式:

    static Object lock = new Object();

    volatile int commonRes = 0;

    public void doSomething() {
        System.out.println("Before statement " + commonRes);

        synchronized (lock) {
            //some process
            commonRes++;
        }
        //Do something else
        System.out.println("After statement " + commonRes);
    }

我有两个问题:

  1. 这是好方法吗?
  2. lock应该volatile吗?

2 个答案:

答案 0 :(得分:4)

如果两个线程使用相同的对象引用同一个文件,则不需要单独的static对象。由于您的班级来自Object,您也可以使用

synchronized(this) { ... }

或覆盖整个方法的简写形式

public synchronized void doSomething() { ... }

volatile隐含在synchronized访问中 - 锁定原语意识到它们需要是线程安全的。

答案 1 :(得分:1)

  

这是好方法吗?

在多线程环境中锁定资源总是好的,但据我所知,标记为volatile并且资源上的同步是多余的,因为两者在发布的场景中完成了几乎相同的事情。

当我使用synchronized块时,我更喜欢像这样锁定类:

synchronized(MyClass.class) {
...
}

为什么我这样做:

  • 将阻止静态和非静态方法。
  • 没有其他外部对象可以锁定您的对象并可能产生微妙的错误。

在大多数情况下仍然像你一样使用synchronized块也是可以的(有点像我喜欢做的那样),但如果遇到问题(性能,你无法完成的事情,饥饿),我建议使用像ReentrantLock这样的结构 它提供了更大的灵活性,可能提供一些奖励表现。此外,它还可以完成synchronized块无法完成的任务。

ReadWriteLockReentrantReadWriteLock之类的内容在某些情况下可以很好地为您服务,因此也值得一读。

  

锁定应该是不稳定的吗?

据我所知,没有理由。锁定对象隐含为volatile之类的。