Synchronization: some solutions

The fundamental problem in the previous program was that there were two threads modifying the fields of the same object. Furthermore the order in which the fields were modified is indeterminate.

There are a number of possible solutions to this problem. Not all solutions are valid in all situations. For example, one of the simplest and most direct is to make the object immutable; that is, not to allow it to change after it's been constructed. You can guarantee this by making all fields private, not providing any setter methods, and not allowing any non-constructor method in the class to change the value of a field. However, this solution is inappropriate for this problem because the count() method must change the field count.

You can do a similar thing by declaring fields to be final. This way they can't be changed after the object is constructed. This isn't always practical, however.

In this example, it would be simple to make count a local variable instead of a field. This is a relatively uncommon solution (why?), but it does work for this case, primarily because this is a toy example.

public class Counter {

  public void count() {
    int count = 0;
    int limit = 100;
    while (count++ != limit)  System.out.println(count); 
  }

}

By making count a local variable instead of a field, each thread that invokes the count() method on this object gets a separate and different count. Each time a method is called, a separate stack frame is set up for its variables and arguments. Different invocations of a method do not share variables. However this has changed the meaning of the program. Now each thread counts from 0 to 100. If this is what was originally intended this is fine. However if the intention was for the first thread to count from 0 to 100 and the second thread to count from 101 to 200, then this solution's no good.


Previous | Next | Top | Cafe au Lait

Copyright 1997, 2002 Elliotte Rusty Harold
elharo@metalab.unc.edu
Last Modified April 18, 2002