当前位置: 首页 > 知识库问答 >
问题:

澄清参数块同步的含义

端木兴国
2023-03-14

我想知道这个表达式是否正确,是否意味着:我在字段状态上加了一个写锁,然后更改它。如果不是,我想知道参数的含义是什么,因为我总是看到这个。

public class Example {
    private int status;
    public Example(int status){
        this.status = status;
    }
    public void setStatus(int newStatus){
        synchronized(this.status){
            this.status = newStatus;
        }
     }
}

共有3个答案

聂琨
2023-03-14

我看到您正在同步字段this.status,这是一个int。不可能通过原始类型同步。只有在对象或类上。

为什么不考虑使用< code>AtomicInteger:

    public class Example
{
  private AtomicInteger status;

  public Example(int status)
  {
    this.status = new AtomicInteger(status);
  }

  public void setStatus(int newStatus)
  {
    this.status.getAndSet(newStatus);
  }
}
徐杰
2023-03-14

不,你的表情并不意味着你的想法。同步块的参数是你在运行同步块之前获取的锁,并在最后释放。在 Java 中,从 Object 继承的所有内容都可以用作锁(所以不,int 不能用作锁)。

一个锁一次只能被一个线程持有,但是如果不同的对象作为参数给出,同一个同步块中的代码可以同时在几个线程中运行。另一方面,如果两个不同的同步块被赋予相同的锁作为参数,那么这两个线程将不能从不同的同步块运行不同的代码。

人们经常使用< code>this作为锁,但也经常使用专门用于锁的对象,这就是OldCurmudgeon在她的回答中所做的。

鲍高扬
2023-03-14

此代码有几个问题:

>

  • 您不能在原语上同步

    您可以将其更改为Integer,但请参见下文。

    在非最终对象上同步不是一个好主意。

    你可以让它成为最终的

    同步时更改字段将以一些非常模糊的方式中断。现在是最终它将不被允许。

    可能最好在另一个字段上同步。

    您还应该为完整性提供一个get方法。

    解决了所有这些问题后,您的代码看起来像这样:

    public class Example {
      private final Object statusLock = new Object();
      private Integer status;
    
      public Example(Integer status) {
        this.status = status;
      }
    
      public void setStatus(Integer newStatus) {
        synchronized (statusLock) {
          status = newStatus;
        }
      }
    
    
      public Integer getStatus() {
        return status;
      }
    }
    

    现在,有了这段代码,你的问题的答案是。这里发生的事情是,当您更改< code>status字段的值时,通过set方法从任何其他线程锁定对它的所有访问。

    请注意,我不在 get 方法中同步。如果我这样做了,那么上述陈述就会改变。

  •  类似资料:
    • 我假设InitialRAMPercentage设置启动时堆的数量,MinRAMPercentage和MaxRAMPercentage设置JVM允许收缩/增长到的堆的底部和顶部限制。 显然情况并非如此。当我启动一个JVM(使用UseContainerSupport,具有这些新的内存设置参数)时,如下所示: InitialHeap和MaxHeap设置后,我无法找到“最小堆大小”值;因此,MinramP

    • 问题内容: 参考:https : //bugs.java.com/bugdatabase/view_bug.do?bug_id=8186315 我真的很难找出MinRAMPercentage的功能,尤其是与InitialRAMPercentage相比。 我假设InitialRAMPercentage设置了启动时的堆数量,MinRAMPercentage和MaxRAMPercentage设置了允许J

    • 问题内容: 我有一张桌子Table1 当我使用以下查询查询该表时 我得到的输出为 但是以同样的方式,当我使用以下查询时,我没有任何输出。 有人请给我指导,为什么它会那样工作,以及如何使用rownum。 问题答案: 汤姆回答了许多与Oracle有关的问题 简而言之,在应用where子句之后和应用order by子句之前,rownum可用。 在RowNum = 2的情况下,where子句中的谓词将永远

    • 问题内容: 每个人都知道,或者至少每个程序员都应该知道,使用该类型可能会导致精度错误。但是,在某些情况下,精确的解决方案将是不错的选择,并且在某些情况下,使用epsilon值进行比较是不够的。无论如何,这不是重点。 我知道Python中的类型,但从未尝试使用它。它指出“十进制数可以精确表示”,我认为这意味着可以实现任何实数的聪明实现。我的第一次尝试是: 非常令人失望,我回到文档中并继续阅读: 算术

    • 我希望下面的代码中有,但它运行良好。 根据JavaDoc for: 这个类的所有“Collection view Methods”返回的迭代器都是快速失败的:如果在迭代器创建后的任何时候,以任何方式(除了通过迭代器自己的remove方法)修改了映射,则迭代器将抛出一个ConcurrentModificationException。 因此,由于我在获得之后修改了,所以我应该得到。为什么不扔?

    • 问题内容: 我正在查看包含同步方法的第三方库中的一些代码,在此方法中,有一个锁定在实例变量上的同步块。与此类似: 这有意义吗?如果是这样,在同步方法中使用同步语句有什么好处? 鉴于同步方法锁定了整个对象,对我来说似乎是多余的。在使用非私有的实例变量时,这种方法是否有意义? 问题答案: 在您的示例中,该方法 同时 锁定了和的实例。其他方法可能仅锁定对象的实例 或 对象。 因此,是的,这完全取决于他们