synchronized - only a single thread can execute a method or
block at one time.
not only does synchronization prevent a thread from observing
an object in an inconsistent state, but it ensures that each thread entering a
synchronized method or block sees the effects of all previous modifications that
were guarded by the same lock.
synchronization is required for reliable communication between
threads as well as for mutual exclusion.
principles
do not use thread.stop.
synchronization has no effect unless both read and write
operations are synchronized.
/**
* demo for 66 synchronize access to shared mutable
data.
*/
package com.effectivejava.concurrency;
import
java.util.concurrent.timeunit;
* properly
synchronized cooperative thread termination
* @author kaibo
*
public
class stopthread {
private
static boolean stoprequested;
private static synchronized void requeststop() {
stoprequested =
true;
system.out.println("request
stop from another thread.");
}
static synchronized boolean stoprequested()
{
return stoprequested;
}
static void main(string[] args)
throws interruptedexception {
thread backgroundthread =
new thread(new runnable() {
public void
run() {
int i = 0;
while
(!stoprequested())
system.out.println(i++);
});
backgroundthread.start();
timeunit.seconds.sleep(1);
requeststop();
* cooperative thread termination with a volatile
field
class stopthreadwithvolatile {
private static volatile boolean stoprequested;
public static void
main(string[] args)
(!stoprequested)
stoprequested = true;
note
operator(++) is not atomic - if a second thread reads the field
between the time a thread reads the old value and writes back a new one, the
second thread will see the same value as the first and return the same serial
number.
// broken - requires synchronization!
private static volatile int nextserialnumber = 0;
static int generateserialnumber() {
return nextserialnumber++;
// correct way
private static final atomic long nextserialnum =
new atomiclong();
public static
long generateserialnumber()
return
nextserialnum.getandincrement();
4. confine mutable data to a single thread
summary
when multiple threads
share mutable data, each thread that reads or writes the data must perform
synchronization. without synchronization, there is no guarantee that one
thread’s changes will be visible to another. the penalties for failing to
synchronize shared mutable data are liveness and safety failures. if you
need only
inter-thread communication,
and not mutual exclusion, the volatile modifier is an acceptable form of
synchronization, but it can be tricky to use correctly.