对象同步,java [重复]
Posted
技术标签:
【中文标题】对象同步,java [重复]【英文标题】:Synchronization on object, java [duplicate] 【发布时间】:2016-05-08 04:33:37 【问题描述】:我正在阅读有关 Java 中的多线程编程的 Oracle 教程。我不明白为什么要创建一个新对象来同步代码的某些部分?为什么要创建新的虚拟对象?
我明白创建这两个对象会阻止编译器重新排序由构造 syncronized(lock1) 保护的代码段
但是,我想知道我可以在构造 syncronized(lock1) 中使用任何其他对象(MsLunch 除外)吗?
引入这种构造 syncronized(lock1) 的动机是什么?
这是我关心的一段代码:
public class MsLunch
private long c1 = 0;
private long c2 = 0;
// what is the purpose of these two objects? how do they serve as locks?
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1()
synchronized(lock1)
c1++;
public void inc2()
synchronized(lock2)
c2++;
【问题讨论】:
你可以看到这个问题***.com/questions/1085709/… 【参考方案1】:线程访问锁以检查代码当前是否“正在使用”,或者它们是否可以在自己锁定对象后执行它。 您可能认为它可能是自动的,但它有一个编译器无法推断的用途:您可以使用同一个锁来同步多个代码块,同时限制对其中任何一个的访问。
【讨论】:
我想知道我可以在构造 syncronized(lock1) 中使用任何其他对象(MsLunch 除外)吗?引入这种构造 syncronized(lock1) 的动机是什么?【参考方案2】:首先是一些基础知识:
同步对象用作打开限制区域(同步块)的门的钥匙。
只要一个线程进入这个限制区域,它就会持有监视器(锁),这样其他线程就不能进入。当一个线程退出限制区域时,它会释放监视器,另一个线程可以占用它。
这意味着每个使用相同同步对象的同步块都会阻止其他线程进入,直到监视器可用(解锁)。
创建新虚拟对象的原因是什么?
原因是您应该使用其他对象无法访问的对象,而不是使用它们的对象。这就是同步对象为private
的原因。如果其他人可以访问它们,其他人可能会在应用程序某处的同步块中使用它们。如果同步对象是例如public
然后所有其他对象都可以使用它。这可能会导致意外使用,并可能导致死锁。
所以你应该确定谁会得到同步对象的引用。
【讨论】:
【参考方案3】:在我看来,dummy Object
只是代表同步点。
为了同步不同的线程,您必须能够声明同步点并且(如果需要)允许从代码的不同部分访问该点。例如:
private Object lock = new Object();
public void inc1()
synchronized(lock)
c1++;
public void inc2()
synchronized(lock)
c2++;
在这个例子中,展示了来自不同部分代码的相同同步点的使用。
因为Java是面向对象的语言,即Java中的语言单位是Object,所以我们有这样的结构。
顺便说一句,您可以使用任何对象作为同步点。你甚至可以这样做:
public void inc1()
synchronized(this)
c1++;
【讨论】:
我认为synchronized(this)
与public synchronized void inc1()
相同,即不会有任何缩小。
@mr.M 你是对的,这是同样的事情【参考方案4】:
这两个对象的目的是什么?它们如何用作锁?
如您的代码所示,inc1()
和inc2()
只能由一个线程调用。这意味着每个线程只能增加一次 c1
和 c2
- 但同时由两个不同的线程(因为两个线程在不同的对象上同步)。
如果两个块都像这样同步synchronized(lock1)
,c1
和 c2
不能同时增加。
【讨论】:
以上是关于对象同步,java [重复]的主要内容,如果未能解决你的问题,请参考以下文章