首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java多线程

Java多线程
EN

Stack Overflow用户
提问于 2013-08-14 07:06:31
回答 3查看 911关注 0票数 0

我是一个新手java程序员,对下面的代码片段有点困惑。这是否意味着第一个线程将与第三个线程共享锁?希望有人能帮我澄清。提前谢谢。

代码语言:javascript
运行
复制
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();
    }
}    
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-08-14 07:33:11

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

您应该看看finalvolatile关键字。

final意味着一旦指向某个地方,引用就不能被重新指向。这是锁的好主意。如果您将声明更改为

代码语言:javascript
运行
复制
final static Object o = new Object();

您可以保证o不能更改,并且所有同步都将位于同一个对象上。

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

票数 2
EN

Stack Overflow用户

发布于 2013-08-14 07:16:23

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

看一看代码的这一部分:

代码语言:javascript
运行
复制
 if ( counter++ == 1 )    //confused in here.                
        o = new Object();

这部分根本不需要使代码线程安全。删除上面的代码,这会造成混乱。您已经在声明对象时创建了对象的实例。现在,为了确保所有线程之间的线程安全,让它们获得您已经创建的相同对象的锁。

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

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

票数 1
EN

Stack Overflow用户

发布于 2013-08-14 08:57:34

这是否意味着第一个线程将与第三个线程共享锁?

是的,此外,由于:

  1. 非易失性static int counter = 0变量
  2. 非原子操作++

每个线程都有自己的变量counter副本。这意味着以下条件永远不会是true

代码语言:javascript
运行
复制
if ( counter++ == 1 )    
   o = new Object();

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18225283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档