【问题标题】:Synchronization on object, java [duplicate]对象同步,java [重复]
【发布时间】: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++;
              } 
       }
 }

【问题讨论】:

标签: java multithreading


【解决方案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 不能同时增加。

    【讨论】:

      猜你喜欢
      • 2014-11-15
      • 2015-07-13
      • 2011-12-12
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 2011-11-25
      • 2013-04-25
      • 2015-03-13
      相关资源
      最近更新 更多