Java synchronized块 - 锁定对象

时间:2013-08-09 23:06:33

标签: java synchronized

在示例代码中

public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();

public void inc1() {
    synchronized(lock1) {
        c1++;
    }
}

public void inc2() {
    synchronized(lock2) {
        c2++;
    }
}
}

this页上,

lock1 lock2 正在控制 c1 c2 上的更新。

然而,

    synchronized(lock2) 

正在获取对象 lock1 的锁定,并在同步块

时释放它
    synchronized(lock1) {
        c1++;
    }

已执行。

正在执行此块时,可能会有 对象的成员 c1 的更新仍然 - 我不这样做 了解如何防止此更新 与代码中的 lock1 同步。

对象 lock1 有独占访问权限 - 没有别的(?)

那么,实现如何

public void inc1() {
    synchronized(lock1) {
        c1++;
    }
}

在上面的代码中与

不同
public void synchronized inc1() {
        c1++;
}

甚至

public void inc1() {
    synchronized(c1) {
        //do something on c1
    }
}

c1 是一个对象但不是一个原语?

我在这里缺少什么?

注意:我看到了

What is the difference between synchronized on lockObject and using this as the lock?

Java synchronized method lock on object, or method?

在其他一些讨论中。

5 个答案:

答案 0 :(得分:6)

实施1。

您正在锁定lock1对象。其他任何需要锁定的lock1都无法执行。让两个方法锁定不同的对象意味着这两个方法可以并发运行,但没有两个线程可以同时运行相同的方法。

实施2。

创建方法synchronized意味着整个方法体隐式位于synchronized(this)块中(如果方法为Class,则在static对象上同步。如果两者都是方法是synchronized,然后一个方法会阻止另一个方法同时运行,这与将两个方法锁定在不同对象上的方法不同。

实施3。

如果c1是一个对象而不是一个原语,那么语义与实现1非常相似 - 锁定一个显式对象。

答案 1 :(得分:0)

据我所知,您的陈述不正确。您链接的页面并未说明您在问题中声明的内容。这就是锁的工作方式:锁根本不会阻止访问对象的线程。锁只会阻止获取同一锁的另一个线程,而另一个线程已经获得该锁。

这意味着可能发生这种情况:

Thread A: synchronize (lockObject)
Thread B: lockObject.toString();
Thread A: release the lock on lockObject

当两个线程同时想要相同的锁时会发生这种情况:

Thread A: synchronize (lockObject)
Thread B: synchronize (lockObject) // This will block until (1) !
Thread A: do some stuff and then release lock on lockObject
Thread B: gets the lock (1)

然而:

public void synchronized inc1() {
    c1++;
}

与:

完全相同
public void inc1() {
    synchronized(this) {
        c1++;
    }
}

答案 2 :(得分:0)

在没有指定锁定对象的情况下标记块或方法synchronized在拥有该方法的对象上进行同步;在这种情况下,MsLunch实例。它相当于synchronized(this)。锁定对象习惯用法的目的是打破锁定,以便可以单独操作c1c2synchronized块只能在对象上同步,而不能在基元上同步。

答案 3 :(得分:0)

synchronized(lock2){
  // do sth
}

实际上是获取对象lock2的锁定

其中

public void synchronized inc1() {
        c1++;
}

获取此对象的对象。

一旦程序离开块,将释放

synchronized获取的锁。

答案 4 :(得分:0)

我遇到一个阻碍锁定的线程

for(;;){synchronized(lockObject){
...
}}

我想Java不想在第一次机会时自行解锁它。

使用java.util.concurrent.locks.ReentrantLock修复了问题

static ReentrantLock lock = new ReentrantLock();
for(;;){
  lock.lock();
  ...
  lock.unlock();
}