问题
i would like to know if this expression it is correct and if it means this: i put a write lock over the field status, and than i change it. If not, i would like to know what is the meaning of the paramenter, because i see always this.
public class Example {
private int status;
public Example(int status){
this.status = status;
}
public void setStatus(int newStatus){
synchronized(this.status){
this.status = newStatus;
}
}
}
回答1:
There are several things wrong with this code:
You cannot
synchronizeon a primitive.You could change it to an
Integerbut see below.Synchronizing on a non-final object is not a good idea.
You could make it
finalChanging a field while it is being
synchronizedon is going to break in some very obscure ways. And now it isfinalit will not be allowed.Probably better to synchronize on another field.
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.
回答2:
No, your expression doesn't mean what you think. The parameter of the synchronized block is the lock you acquire before running the synchronized block and release at the end. In Java, everything that inherit from Object can be used as a lock (so no, int can't be used as lock).
A lock can only be held by one thread at a time, but the code within a same synchronized block can be running within several threads at the same time if different objects were given as parameters. On the other hand, two thread will not be able to run different codes from different synchronized blocks if the two different synchronized block are given the same lock as a parameter.
People often use this as a lock, but it is also common to use an object specifically intended to be a lock, which is what OldCurmudgeon did in her answer.
回答3:
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);
}
}
来源:https://stackoverflow.com/questions/19154111/clarification-on-the-meaning-of-the-parameter-block-synchronization