下面的代码会发生什么?同步有效吗?这是一道面试题。
class T
{
public static void main(String args[])
{
Object myObject = new Object();
synchronized (myObject)
{
myObject = new Object();
} // end sync
}
}
下面的代码会发生什么?同步有效吗?这是一道面试题。
class T
{
public static void main(String args[])
{
Object myObject = new Object();
synchronized (myObject)
{
myObject = new Object();
} // end sync
}
}
每次进入同步块时,都会在不同的对象上同步。大多数情况下,除了让你感到困惑之外,这不会做任何事情,但是两个线程看到同一个对象并等待的可能性很小。
出于这个原因,如果您正在同步的字段不是final
.
它仍然释放获取的同一个监视器,但是任何其他也使用锁定的代码myObject
(这里不可能,因为它是一个局部变量,使得同步基本上毫无意义)将开始使用新对象。
不要忘记同步应用于对象(或者更确切地说,与对象关联的监视器) - 而不是变量。获取/释放的监视器仅取决于到达同步块开始时的表达式值。在同步块结束时不会重新计算表达式。
不,它不起作用。每当有新线程进入时,myObject
就会创建一个新线程。特别是现在这myObject
是一个局部变量!
即使myObject
是类成员,它也不起作用,因为您将更改要锁定的对象。有关详细说明,请参阅有关非最终字段同步的问题。
我看不出这段代码背后的原因,因为对象没有被任何线程共享。在任何情况下,删除同步块都不会影响实际结果。它只会让你的代码运行得更快
你需要先获取myObject的锁,如果这个锁被阻塞了,你必须等到锁被释放。
同步需要多线程环境。但是您的代码似乎与并发无关。所以我很遗憾地告诉您,没有任何事情会发生。
运行代码并分析结果。
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();
}
}