ReentrantLock中的混乱

时间:2015-07-28 19:46:09

标签: java multithreading

我试图理解ReentrantLock在Java中的内部工作。

我创建了一个例子: -

bash

现在我的问题是有2个线程对象和2个可运行对象和2个线程。每个线程应在其自己的堆栈帧上运行run方法,以用于不同的可运行对象。如果每个线程在具有不同runnable对象的堆栈上运行自己的run方法,则输出应该是不同的。

我见过我们创建几个线程的示例,我们将共享对象传递给这些线程,我们在该共享对象的方法中锁定和解锁。这里没有共享对象。有两个runnable对象传递给2个线程对象,但runnable对象表现为共享对象。

请您解释一下可能导致此输出的原因?或者可以提供相同的澄清

由于

2 个答案:

答案 0 :(得分:3)

  

此处对象未共享

两个线程都运行自己的Runnable实例是正确的,因此两个线程都没有共享一个公共的Runnable。

但是两个Runnable实例都使用了所包含类的共享对象,这就是锁对象。因此,他们在这个对象的帮助下彼此同步。只要另一个线程通过调用

保持锁定,就会阻塞一个线程
lock.tryLock(500, TimeUnit.MILLISECONDS)

为什么两个Runnable实例都可以访问锁定对象,该对象被定义为类ReentrantLockingDemo的私有变量,这里将解释Anonyomous Classes

所以当你写

private Runnable newRunable() {

    return new Runnable() {...};
}

您创建了一个从Runnable继承的匿名内部类的新实例,该实例可以访问外部类的所有final(或Java 8也是所有有效的最终)字段。

因此,即使您没有将共享对象显式传递给Runnable实例,它们也会使用共享对象进行同步,在这种情况下是锁定对象。

答案 1 :(得分:2)

  

这里没有共享对象。

不会共享Runnable和Threas。

有两个共享的对象ReentrantLockingDemo.thisReentrantLockingDemo.this.lock正是共享锁才能使其发挥作用。

  

runnable对象表现为共享对象。

您没有打印出Runnable的详细信息,因此您无法确定这一点。尝试在run()

中添加以下内容
System.out.println(this);

它应该在它之后用不同的hashCode打印类名。

  

总是这个锁对象在单个对象或更多对象(如上例所示)的情况下在线程之间共享以进行同步吗?

锁对象没有什么特别之处,这意味着必须共享它。共享对象的原因是由于数据结构的布局方式。您有一个ReentrantLockingDemo实例,它有一个字段,它是ReentrantLock的一个实例。没有比这更复杂或更特殊的了。

  

虽然在不同的对象上使用它不会起任何作用,因为实例变量也会变得线程安全,因为对象是不同的。

唯一different个对象是两个Runnable

  

。在这种情况下,锁在线程之间共享

当两个线程都使用相同的对象时。在这种情况下,只有其中一个,所以毫无疑问它可以分享。

  

您能为上述提供任何链接吗?

有时我们会想到,因为问题很难掌握,所以必须复杂化。实际上它非常非常简单。

您只创建一个锁,因此必须共享。