以下代码会发生什么?同步是否有效?这是一个面试问题。
class T
{
public static void main(String args[])
{
Object myObject = new Object();
synchronized (myObject)
{
myObject = new Object();
} // end sync
}
}
答案 0 :(得分:4)
每次进入同步块时,都会同步另一个对象。大多数情况下,除了让您感到困惑之外,这不会做任何事情,但是两个线程很可能会看到相同的对象并等待。
因此,如果您要在不是final
的字段上进行同步,任何代码分析器都会向您发出警告。
答案 1 :(得分:1)
它仍然释放了获取的同一个监视器,但是任何其他代码也使用myObject
锁定(这里不可能,因为它是一个局部变量,使同步基本没有意义)将开始使用新对象。 / p>
不要忘记同步应用于对象(或者更确切地说,与对象关联的监视器) - 而不是变量。正在获取/释放的监视器取决于达到同步块的 start 时表达式的值。表达式是在同步块结束时重新评估 。
答案 2 :(得分:0)
不,它不起作用。每当有新线程进入时,都会创建一个新的myObject
。特别是现在myObject
是一个局部变量!
即使myObject
是类成员也不会起作用,因为您要更改要锁定的对象。有关详细说明,请参阅有关synchronization of non-final field的问题。
答案 3 :(得分:0)
我没有看到此代码背后的原因,因为任何线程都不共享Object。在任何情况下,删除同步块都不会影响实际结果。它只会让你的代码运行得更快
答案 4 :(得分:0)
首先需要获取myObject的锁定,如果此锁定被阻止,则必须等到锁定被释放。
同步需要多线程环境。但是你的代码似乎与并发无关。所以我很遗憾地告诉你,没有任何事情会发生。
答案 5 :(得分:0)
运行代码并分析结果。
public class Test {
static Foo o = new Foo(0);
static class Foo {
private int i = 0;
Foo(int i) {
this.i = i;
}
public void addOnce() {
this.i++;
}
public String toString() {
return String.valueOf(i);
}
}
public static void main(String args[]) {
test1();
try {Thread.sleep(10000);} catch (Exception e) {}
test2();
}
public static void test1() {
Runnable r = new Runnable() {
public void run() {
synchronized (o) {
System.out.println("1------>"+o);
o = new Foo(1);
try {Thread.sleep(3000);} catch (Exception e) {}
System.out.println("1------>"+o);
}
}
};
new Thread(r).start();
new Thread(r).start();
}
public static void test2() {
Runnable r = new Runnable() {
public void run() {
synchronized (o) {
System.out.println("2------>"+o);
o.addOnce();
try {Thread.sleep(3000);} catch (Exception e) {}
System.out.println("2------>"+o);
}
}
};
new Thread(r).start();
new Thread(r).start();
}
}