对象同步,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() 只能由一个线程调用。这意味着每个线程只能增加一次 c1c2 - 但同时由两个不同的线程(因为两个线程在不同的对象上同步)。

如果两个块都像这样同步synchronized(lock1)c1c2 不能同时增加。

【讨论】:

以上是关于对象同步,java [重复]的主要内容,如果未能解决你的问题,请参考以下文章

同步方法或同步块:在java中编写单例类时哪一个更好? [重复]

同步关键字不使函数同步:Java [重复]

java同步(this)范围[重复]

Java中“this”或私有对象的同步? [复制]

java

Java删除ArrayList中的重复对象[重复]