I reviewed some concepts about thread again by reading the thinking in Java today. Here is some key points I want to note here.
1) Why Synchronized is necessary?
When a program have two or more threads access to a shared recourse, there may be some conflict between threads. For example,
//in thread 1
int sharedValue=0;
//********critical zone***********
sharedValue++; // thread maybe stop here
sharedValue++;
</pre><p></p><p>Now, suppose thread 2 intends to get the value of sharedValue (through some get method or read directly or whatever). Moreover, in this program, thread 2 are coded to process with even sharedValue. In that situation, problems occur. Maybe, when thread 1 just reach the first sharedValue++ and then be terminated or interrupted. Then sharedValue is a unexpected value for thread 2 and the program goes wrong. </p><p></p><p>the codes under the comments is a critical zone which should only access by one thread in one time. In java, the keyword <strong>synchronized </strong>is designed for that. </p><p>synchronized: apply for object, methods, classes and even code block {}. If something is labeled with that, this object,/value /methods,/classes / code block is not allowed to be access by multi- threads in the same time. </p><p></p><p>2) suggestions for the use of synchronized</p><p>a) if a value is labeled with synchronized, any methods can be access by other threads should also be synchronized. Same reason for synchronized method/ class</p><p>b) if synchronized is not used properly, programs only have chance to be wrong. In other word, it maybe seems OK because it only has a small chance to go wrong.</p><p>c) yield() increased that chance, some you can add some useless yield() to test your codes.</p><p></p><p>3) Lock</p><p>Besides synchronized, there is a less elegant way to deal with the critical zone. <strong>java.util.concurrent.locks.*;</strong></p><p>However, sometimes, the lock is more flexible. Here is a example codes from Thinking In Java"</p><p><pre name="code" class="java">int currentEvenValue=0;
Lock lock=new ReentranLock();
public int next(){
lock.lock();
try{
<span style="white-space:pre"> </span>currentEvenValue++;
<span style="white-space:pre"> </span>currentEvenValue++;
<span style="white-space:pre"> </span>return currentEvenValue;
}finally{
<span style="white-space:pre"> </span>lock.unlock();
}
}
You must place a try-finally statement with unlock() because it is the only way to ensure the unclock() is done.
In some situation, lock can not replaced by synchronized. For example, you want to lock for a certain time and release it.