2009-05-17 49 views
3

传递给synchronized的参数的意义是什么?块级同步

synchronized (parameter) 
{ 

} 

实现块级同步。在某处我看到的代码像

class test 
{ 
    public static final int lock =1; 

    ... 

    synchronized(lock){ 
     ... 
    } 
} 

我不明白这段代码的目的。

任何人都可以给我一个更好的例子和/或解释它吗?

回答

6

此:

public synchronized void blah() { 
    // do stuff 
} 

在语义上等同于:

public void blah() { 
    synchronized (this) { 
    // do stuff 
    } 
} 

有些人不喜欢用“这”同步,部分原因是因为它是公共的(在该实例可见到外部代码)。这就是为什么你最终使用专用锁人:

​​

的好处是,锁不类的外部可见光加你可以创建几个锁处理更细粒度锁的情况。

+0

我认为在这个例子中,你必须删除“静态”,因为“静态”LOCK将适用于Foo类的所有实例。 – ultraon 2016-12-23 11:57:05

2

​​声明(ref:here)的目的是为了确保在多线程应用程序中,在给定时间只有一个线程可以访问关键数据结构。例如,如果让两个线程同时更改相同的数据结构,那么数据结构将被破坏,然后通常使用锁来保护它。

在现实世界中,考虑一个公共厕所有钥匙的模拟器,挂在中心位置。在您使用厕所之前,您需要钥匙,不仅可以进入,而且还可以保证任何人都不会同时进入同一个厕所。他们必须等待钥匙可用。

这就是这样的锁构造如何工作。

在这种情况下,​​关键字的参数是关键。你锁定钥匙,做你需要做的事情,然后你解锁钥匙,让其他人可以使用钥匙。如果其他线程试图在当前被另一个线程锁定的情况下锁定该键,则该线程将不得不等待。

1

传递到synchronized的对象实例是“锁定单位”。其他尝试锁定同一实例的线程都将等待轮到它。

人们使用它而不是方法级别同步关键字(锁定执行类对象的实例)的原因是他们可能想要更细粒度或不同的东西来等待锁定,多线程算法的设计。

11

这是锁定的参考。基本上两个线程不会同时执行使用相同引用同步的代码块。正如Cletus所说的,同步的方法方法大多等同于在方法内部使用synchronized (this)

我非常希望你看到的示例代码不是这样的就是这样 - 你试图在一个原始变量上进行同步。同步只在监视器上工作(通过参考) - 即使它合法代码,x将被装箱,这将导致一些奇怪的行为,因为一些整数将始终装箱到相同的引用,并且其他人会在每次包装箱时创建一个新对象。幸运的是,Java编译器意识到这是一个非常糟糕的主意,并会为您发布的代码提供编译时错误。

更合理的代码是:

class Test 
{ 
    private static final Object lock = new Object(); 

    ... 

    synchronized(lock){ 
     ... 
    } 
} 

我所做的锁定私人,并改变其类型设置为Object。它是否应该是静态的取决于情况 - 如果你想访问/改变来自多个线程的静态数据,通常会使用静态变量;当你想从多个线程访问/更改每个实例的数据时,实例变量通常用于锁定。

+0

这是真的 - 将编辑。 (静态可能是好的,取决于上下文。) – 2009-05-17 18:51:15

+0

公共和静态锁也不是好主意:-)顺便说一句,在Java中,整数1总是被装箱到同一个对象。 – 2009-05-17 18:51:29

2

我不能解释它,因为它不会编译。你不能锁定一个基元。

另一个不好的例子是,将其更改为

public static final Integer lock =1; 

这是一个糟糕的主意,因为小型自动盒装原语缓存,可能有奇怪的副作用(如果这样做了不止一次)