传递给synchronized的参数的意义是什么?块级同步
synchronized (parameter)
{
}
实现块级同步。在某处我看到的代码像
class test
{
public static final int lock =1;
...
synchronized(lock){
...
}
}
我不明白这段代码的目的。
任何人都可以给我一个更好的例子和/或解释它吗?
传递给synchronized的参数的意义是什么?块级同步
synchronized (parameter)
{
}
实现块级同步。在某处我看到的代码像
class test
{
public static final int lock =1;
...
synchronized(lock){
...
}
}
我不明白这段代码的目的。
任何人都可以给我一个更好的例子和/或解释它吗?
此:
public synchronized void blah() {
// do stuff
}
在语义上等同于:
public void blah() {
synchronized (this) {
// do stuff
}
}
有些人不喜欢用“这”同步,部分原因是因为它是公共的(在该实例可见到外部代码)。这就是为什么你最终使用专用锁人:
的好处是,锁不类的外部可见光加你可以创建几个锁处理更细粒度锁的情况。
声明(ref:here)的目的是为了确保在多线程应用程序中,在给定时间只有一个线程可以访问关键数据结构。例如,如果让两个线程同时更改相同的数据结构,那么数据结构将被破坏,然后通常使用锁来保护它。
在现实世界中,考虑一个公共厕所有钥匙的模拟器,挂在中心位置。在您使用厕所之前,您需要钥匙,不仅可以进入,而且还可以保证任何人都不会同时进入同一个厕所。他们必须等待钥匙可用。
这就是这样的锁构造如何工作。
在这种情况下,关键字的参数是关键。你锁定钥匙,做你需要做的事情,然后你解锁钥匙,让其他人可以使用钥匙。如果其他线程试图在当前被另一个线程锁定的情况下锁定该键,则该线程将不得不等待。
传递到synchronized的对象实例是“锁定单位”。其他尝试锁定同一实例的线程都将等待轮到它。
人们使用它而不是方法级别同步关键字(锁定执行类对象的实例)的原因是他们可能想要更细粒度或不同的东西来等待锁定,多线程算法的设计。
这是锁定的参考。基本上两个线程不会同时执行使用相同引用同步的代码块。正如Cletus所说的,同步的方法方法大多等同于在方法内部使用synchronized (this)
。
我非常希望你看到的示例代码不是这样的就是这样 - 你试图在一个原始变量上进行同步。同步只在监视器上工作(通过参考) - 即使它是合法代码,x
将被装箱,这将导致一些奇怪的行为,因为一些整数将始终装箱到相同的引用,并且其他人会在每次包装箱时创建一个新对象。幸运的是,Java编译器意识到这是一个非常糟糕的主意,并会为您发布的代码提供编译时错误。
更合理的代码是:
class Test
{
private static final Object lock = new Object();
...
synchronized(lock){
...
}
}
我所做的锁定私人,并改变其类型设置为Object
。它是否应该是静态的取决于情况 - 如果你想访问/改变来自多个线程的静态数据,通常会使用静态变量;当你想从多个线程访问/更改每个实例的数据时,实例变量通常用于锁定。
这是真的 - 将编辑。 (静态可能是好的,取决于上下文。) – 2009-05-17 18:51:15
公共和静态锁也不是好主意:-)顺便说一句,在Java中,整数1总是被装箱到同一个对象。 – 2009-05-17 18:51:29
我不能解释它,因为它不会编译。你不能锁定一个基元。
另一个不好的例子是,将其更改为
public static final Integer lock =1;
这是一个糟糕的主意,因为小型自动盒装原语缓存,可能有奇怪的副作用(如果这样做了不止一次)
我认为在这个例子中,你必须删除“静态”,因为“静态”LOCK将适用于Foo类的所有实例。 – ultraon 2016-12-23 11:57:05