我是一名新手 Java 程序员,对以下代码片段感到有点困惑。这是否意味着第一个进来的线程将与第三个线程共享锁?希望有人能帮我澄清。提前致谢。
public class T_6 extends Thread {
static Object o = new Object();
static int counter = 0;
int id;
public T_6(int id) {
this.id = id;
}
public void run () {
if ( counter++ == 1 ) //confused in here.
o = new Object();
synchronized ( o ) {
System.err.println( id + " --->" );
try {
sleep(1000);
} catch ( InterruptedException e ) {
System.err.println("Interrupted!");
}
System.err.println( id + " <---" );
}
}
public static void main (String args []) {
new T_6(1).start();
new T_6(2).start();
new T_6(3).start();
}
}
最佳答案
当您达到向上计数和 if 时,您将执行典型的“检查然后执行”操作。这里的问题是多个线程可以同时来到这里。这意味着他们将拥有计数器的本地副本。不同的线程可能都有一个 0 本地副本 - 这意味着它们将计数到 1 并创建新对象 - 所有这些。但它们存储在静态容器中 - 它们可能有也可能没有本地副本。简而言之,这里发生的一切都是偶然的。它们最终可能会在同一个对象上进行同步 - 但它们可能会尝试在不同的对象上进行同步,这意味着它们根本不会同步。
您应该查看 final
和 volatile
关键字。
final
表示引用一旦指向某处就无法重新指向。这对于锁来说是个好主意。如果您将声明更改为
final static Object o = new Object();
保证 o
无法更改,并且所有同步都将在同一个对象上进行。
volatile
表示禁止虚拟机存储变量的线程本地副本。所有读取和写入都必须针对内存。这意味着所有线程都会看到其他线程所做的写入。
关于Java多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18225283/