Java多线程

Java多线程,java,multithreading,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

我是一个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();
    }
}    
公共类T_6扩展线程{
静态对象o=新对象();
静态整数计数器=0;
int-id;
公共T_6(内部id){
this.id=id;
}
公开作废运行(){
if(counter++==1)//在这里混淆了。
o=新对象();
同步(o){
System.err.println(id+“-->”);
试一试{
睡眠(1000);
}捕捉(中断异常e){
System.err.println(“中断!”);
}

System.err.println(id+“为确保多个线程之间正确的同步,所有线程必须在同一对象上获得锁,否则将无法实现同步。

请看一下代码的这一部分:

 if ( counter++ == 1 )    //confused in here.                
        o = new Object();
要使代码线程安全,根本不需要此部分。请删除造成混淆的上述代码。您在声明对象时已创建了该对象的实例。现在,为了确保所有线程之间的线程安全,请使它们获得您已创建的同一对象上的锁。

看这里:
静态最终对象o=new Object();



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

要确保多个线程之间正确的同步,所有线程必须在同一对象上获得锁,否则无法实现同步。

请看一下代码的这一部分:

 if ( counter++ == 1 )    //confused in here.                
        o = new Object();
要使代码线程安全,根本不需要此部分。请删除造成混淆的上述代码。您在声明对象时已创建了该对象的实例。现在,为了确保所有线程之间的线程安全,请使它们获得您已创建的同一对象上的锁。

看这里:
静态最终对象o=new Object();



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

当达到递增计数时,如果执行典型的检查,则执行act操作。这里的问题是,多个线程可以ome同时出现在这里。这意味着它们将拥有
计数器的本地副本。
。不同的线程可能都有一个0本地副本-这意味着它们将计数为1并创建新对象-所有这些对象。但是它们存储在一个静态容器中-它们可能有也可能没有本地副本。简言之,这里发生的任何事情都是一个静态的它们最终可能会在同一个对象上同步,但它们可能会尝试在不同的对象上同步,这意味着它们根本不会同步

您应该看看
最终
volatile
关键字

final
表示引用一旦指向某个地方就不能重新绘制。这对于锁来说是个好主意。如果将声明更改为

final static Object o = new Object();
您可以保证
o
不能更改,并且所有同步都将在同一对象上进行


volatile
表示禁止VM存储变量的线程本地副本。所有读取和写入都必须存储到内存中。这意味着所有线程都会看到其他线程所做的写入操作。

当达到递增计数时,如果执行典型的检查,则执行act操作。这里的问题是,可能会有多个线程出现在这里同时。这意味着它们将拥有
计数器的本地副本。
。不同的线程可能都有一个0本地副本-这意味着它们将计数为1并创建新对象-所有这些对象。但是它们存储在一个静态容器中-它们可能有也可能没有本地副本。简言之,这里发生的任何事情都是偶然的。它们可能最终在同一个对象上同步,但它们可能尝试在不同的对象上同步,这意味着它们根本不会同步

您应该看看
最终
volatile
关键字

final
表示引用一旦指向某个地方就不能重新绘制。这对于锁来说是个好主意。如果将声明更改为

final static Object o = new Object();
您可以保证
o
不能更改,并且所有同步都将在同一对象上进行

volatile
表示禁止VM存储变量的线程本地副本。所有读取和写入都必须存储到内存中。这意味着所有线程都将看到其他线程所做的写入

这是否意味着进入的第一个线程将与 第三个

是的,此外,由于:

  • 非易失性
    静态整数计数器=0
    变量
  • 非原子操作
    ++
  • 每个线程都有自己的变量
    计数器的副本。这意味着以下条件永远不会
    为true

    if ( counter++ == 1 )    
       o = new Object();
    
    这就是为什么在声明
    o
    时,所有这些线程都将在对象
    o
    上共享相同的锁

    这是否意味着进入的第一个线程将与 第三个

    是的,此外,由于:

  • 非易失性
    静态整数计数器=0
    变量
  • 非原子操作
    ++
  • 每个线程都有自己的变量
    计数器的副本。这意味着以下条件永远不会
    为true

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

    这就是为什么当声明
    o

    时,所有这些线程将在对象
    o
    上共享同一个锁的原因。此代码不是线程安全的!这就是我的意思。糟糕的代码。Pl