澄清参数块同步的含义

时间:2013-10-03 08:16:12

标签: java synchronized

我想知道这个表达式是否正确,如果它意味着:我对字段状态进行了写锁定,而不是更改它。如果没有,我想知道参数的含义是什么,因为我总是看到这个

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 个答案:

答案 0 :(得分:5)

此代码有几个问题:

  1. 你不能synchronize原语。

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

  2. 同步非最终对象不是一个好主意。

    您可以将其设为final

  3. synchronized开启时更改字段会以一些非常模糊的方式中断。现在它是final不允许的。

    可能更好地在另一个领域进行同步。

  4. 您还应该提供完整性的get方法。

  5. 修复所有这些问题后,您的代码看起来像这样:

    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;
      }
    }
    

    现在 - 使用此代码 - 您的问题的答案是种类。这里发生的事情是,当您更改其值时,您可以通过任何其他线程锁定<{1}}字段通过set方法对所有的访问权限。

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

答案 1 :(得分:0)

我看到您正在同步this.status字段int。 在基本类型上进行同步是不可能的。仅限于对象或类。

为什么不考虑使用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);
  }
}

答案 2 :(得分:0)

不,你的表达并不代表你的想法。 synchronized块的参数是在运行synchronized块之前获取的锁,并在结束时释放。在Java中,从Object继承的所有东西都可以用作锁(所以不能,int不能用作锁)。

锁一次只能由一个线程保存,但如果给出不同的对象作为参数,则同一块内的代码可以同时在多个线程中运行。另一方面,如果两个不同的同步块被赋予与参数相同的锁,则两个线程将无法从不同的同步块运行不同的代码。

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