CS136, Lecture 35

    1. Monitors and synchronized methods
  1. Impossible problems

Monitors and synchronized methods

More complicated if both need to access the same data.

Can set up what is often called a monitor: Data structure which only allows access by one thread at a time.

Can declare methods in a class to be synchronized. Restricts so only one of synchronized methods can be active at a time. (Ordinarily, several methods may be executing methods of the object at the same time!)

When a synchronized method is running, a "lock" is established on the synchronized methods, so that none can be executed until the lock is released by the executing thread.

Use pair of methods wait and notify when must wait on a condition. Wait releases lock and places thread on a queue waiting to be notified that condition might have changed.

Wait and notify can only be invoked from within synchronized methods (or methods called from within synchronized methods).

Use notifyAll if not sure which object is first in queue.

See code for circular buffer in Buffer folder.

Other strategies for adding concurrency to OO languages:

Each object is a process!

Impossible problems

or

Have I Got a DEAL for You!

Suppose someone wants to sell you a program that will enable you to stop wasting lots of time in your programs. They will sell you a program that will analyze any other program (before you run it) and tell you whether or not it will stop. Should you buy the program (or try to write it yourself)?

You try out the program on lots of your programs and it seems to work properly. Then you get the inspiration to try it out on one last program. Here is the program:

public class Debunker
{ 
	/* CharlatanType contains method halts, which takes a 
		filename as input and returns true iff the program 
		contained in that file is a legal Pascal program that 
		halts on empty input. */

	public static void what(String fileName)
	{
		CharlatanType charlatan = new CharlatanType(); 
		if (charlatan.halts(FileName))
		{
			while (true){}
		}
		// else halt
	}

	public static void main(String[] args)
	{
		what("Debunk.java");
	}
}

Following the usual style in Java, we name the file in which this program is stored, Debunk.java.

We begin executing the program Debunk, but in a few moments smoke starts rising from the computer, and after a few more minutes the machine grinds to a halt showing the frowning Mac face, never to run a program again.

What happened?

Let's analyze the program:

When what("Debunk.java") is executed, the first thing that happens is that Halts("Debunk.java") is called.

It will either return true or false. Look at the cases:

  1. Suppose halts("Debunk.java") returns true (meaning the program in Debunk.java will eventually halt). Then the program goes into an infinite loop, never halting. Thus the program in Debunk.java will never halt. CONTRADICTION!

  2. Suppose halts("Debunk.java") returns true (meaning the program in Debunk.java will not halt). Then the program immediately halts. Thus the program in Debunk.java will eventually halt. CONTRADICTION

What went wrong? The only possibility is that we couldn't possibly have such a program! In other words, without even looking at the code of halts, we have proved that it could not possibly work the way it claimed to. Thus no one could write such a program.

There are many such programs that would be useful to have that are not possible to write. This is discussed further in CS361, Theory of Computation.