Java多线程

时间:2013-08-14 07:06:31

标签: java multithreading

我是一名新手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();
    }
}    

3 个答案:

答案 0 :(得分:2)

当你达到向上计数时,如果你做了典型的检查然后行动。这里的问题是几个线程可以同时到达这里。这意味着他们将拥有counter的本地副本。不同的线程可能都有0个本地副本 - 这意味着它们将最多计数1并创建新对象 - 所有这些都是。但它们存储在一个静态容器中 - 它们可能有也可能没有本地副本。简而言之,这里发生的任何事情都是偶然的。它们最终可能会在同一个对象上进行同步 - 但它们可能会尝试在不同的对象上进行同步,这意味着它们根本不会同步。

您应该查看finalvolatile个关键字。

final表示某个引用在某处指向后无法重新指定。锁是一个好主意。如果您将声明更改为

final static Object o = new Object();

保证o无法更改,并且所有同步都将在同一对象上。

volatile表示禁止VM存储变量的线程局部副本。所有读写操作必须是内存。这意味着所有线程都将看到其他线程执行的写操作。

答案 1 :(得分:1)

为了确保多个线程之间正确的同步,所有人必须获取对同一对象的锁定,否则将无法实现同步。

看一下代码的这一部分:

 if ( counter++ == 1 )    //confused in here.                
        o = new Object();

这部分根本不需要使代码线程安全。删除导致混淆的上述代码。您在声明对象时已经创建了该对象的实例。现在要确保所有线程之间的线程安全,让它们获取已经创建的同一对象的锁定。

看这里:static final Object o = new Object();

只需将对象设为最终,以确保您不会错误/有意地在代码中的任何其他位置分配新值。您可以以同步方式直接使用此对象以确保线程安全。

答案 2 :(得分:0)

  

这是否意味着第一个进入的线程将与之共享锁定   第三个?

是的,此外,由于:

  1. 非易失性static int counter = 0变量
  2. 非原子操作++
  3. 每个线程都有自己的变量counter副本。这意味着以下条件永远不会true

    if ( counter++ == 1 )    
       o = new Object();
    

    这就是为什么所有这些线程将在声明o时初始化的对象o上共享同一个锁。