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) {
...
}
}
我不理解这段代码的目的。
有没有人能给我一个更好的例子并/或者解释一下?
这是需要加锁的引用。基本上,两个线程不会同时执行使用相同引用同步的代码块。就像Cletus所说的那样,一个同步的 方法 大多等同于在方法内部使用 synchronized (this)
。
我非常希望你看到的示例代码不要像那样 - 你正在尝试对原始变量进行同步。同步仅适用于监视器(通过引用)- 即使这是合法代码,x
也会被装箱,这将导致一些非常奇怪的行为,因为某些整数将永远装箱为相同的引用,而其他整数每次装箱时都会创建一个新对象。幸运的是,Java编译器意识到这是一个非常糟糕的想法,并且会为您发布的代码提供编译时错误。
更合理的代码是:
class Test
{
private static final Object lock = new Object();
...
synchronized(lock){
...
}
}
我已将锁定设为私有,并将其类型更改为Object
。无论是否应该静态取决于情况 - 基本上,如果您想从多个线程访问/更改静态数据,则通常使用静态变量;当您想从多个线程访问/更改每个实例数据时,通常使用实例变量作为锁。
这个:
public synchronized void blah() {
// do stuff
}
语义上等同于:
public void blah() {
synchronized (this) {
// do stuff
}
}
有些人不喜欢使用“this”来进行同步,部分原因是它是公共的(即实例对外部代码可见)。这就是为什么有些人会使用私有锁的原因:
public class Foo
private final static String LOCK = new String("LOCK");
public void blah() {
synchronized (LOCK) {
// do stuff
}
}
}
LOCK不会在类外部可见,而且您可以创建多个锁以处理更细粒度的锁定情况。
由于代码无法编译,我无法解释。原始类型不能被锁定。
另一个不好的例子是将其更改为
public static final Integer lock =1;
synchronized
语句的目的是确保在多线程应用程序中,只有一个线程可以在任何给定时间访问关键数据结构。synchronized
关键字的参数是钥匙。你锁住钥匙,做你需要做的事情,然后解锁钥匙让其他人访问它。如果其他线程尝试在另一个线程正在锁定该钥匙时锁定该钥匙,则该线程将不得不等待。
x
是一个int
。范围在-128到127之间的值保证每次都会装箱到相同的引用 - 而超出该范围,则取决于具体实现。因此,在某些实现中,两个在值x
上同步的代码块将互相阻塞 - 而在其他实现中则不会。 - Jon Skeet