Clarification of synchronization value of parameter block

I would like to know if this expression is correct, and if it means: I set the write lock on the state of the field and change it. If not, I would like to know what this means for the parasector, because I always see it.

public class Example { private int status; public Example(int status){ this.status = status; } public void setStatus(int newStatus){ synchronized(this.status){ this.status = newStatus; } } } 
0
source share
3 answers

There are several things in this code:

  • You cannot synchronize on a primitive.

    You can change it to Integer , but see below.

  • Synchronizing on a non-final entity is not a good idea.

    You can do it final

  • Changing a field when it is synchronized on will break in some very obscure ways. And now final it will not be resolved.

    It might be better to sync in a different field.

  • You should also provide a get method for completeness.

When all these problems are 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. Here, all access to the status field is blocked using the set method from any other thread when its value changes.

Note that I do not synchronize the get method. If I did, this expression would change.

+4
source

I saw that you are synchronizing the this.status field, which is an int . Unable to synchronize with primitive type. Only for objects or classes.

Why not consider using 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); } } 
0
source

No, your expression does not mean what you think. The synchronized block parameter is the lock that you acquire before starting the synchronized block and releasing it at the end. In Java, everything that inherits from Object can be used as a lock (therefore no, int cannot be used as a lock).

A lock can be held only by one thread at a time, but the code inside one synchronized block can be executed simultaneously in several threads if different objects are specified as parameters. On the other hand, two threads will not be able to run different codes from different synchronized blocks if the two different synchronized blocks are assigned the same lock as a parameter.

People often use this as a lock, but they also often use an object specifically designed for locking, as OldCurmudgeon did in her answer.

0
source

Source: https://habr.com/ru/post/985989/


All Articles