0

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

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

3 回答 3

5

There are several things wrong with this code:

  1. You cannot synchronize on a primitive.

    You could change it to an Integer but see below.

  2. Synchronizing on a non-final object is not a good idea.

    You could make it final

  3. Changing a field while it is being synchronized on is going to break in some very obscure ways. And now it is final it will not be allowed.

    Probably better to synchronize on another field.

  4. You should also provide a get method for completeness.

With all of these issue fixed your code looks something like this:

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

Now - with this code - the answer to your question is kind of. What happens here is that you lock all access to the status field through the set method from any other thread while you change it's value.

Notice that I do not synchronise in the get method. If I did then the above statement would change.

于 2013-10-03T08:56:27.580 回答
0

I saw that you are synchronizing the field this.status which is a int. It's impossible to synchronize over a primitive type. Only on objects or classes.

Why not consider using an 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);
  }
}
于 2013-10-03T08:56:35.370 回答
0

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

一个锁一次只能被一个线程持有,但是如果给定不同的对象作为参数,同一个同步块中的代码可以同时在多个线程中运行。另一方面,如果两个不同的同步块被赋予相同的锁作为参数,则两个线程将无法运行来自不同同步块的不同代码。

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

于 2013-10-03T09:06:31.043 回答