Some reader favorites:
EJB fundamentals and session beans
Create a scrollable virtual desktop in Swing
Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API
Java uses the synchronized keyword and java.lang.Object's wait() and notify() methods as synchronization mechanisms. Are there any other mechanisms, like semaphores, built in to Java?
The only synchronization primitives built in to Java are monitors and wait sets, which many programmers have never heard of
because Java hides them behind synchronized, wait(), and notify(). Fortunately, Java allows you to implement all the familiar synchronization schemes on top of monitors and wait sets. At
the end of this answer, we'll look at how to implement our own Semaphore class.
Before we get into that, though, let's go over a little bit of the theory behind it. Every multithreaded programming language needs to have some way for the threads to keep in synch. Take, for example, a program with a thread that produces objects and a thread that consumes them, as seen in the following code snippet:
Object data = null;
public void push(Object d) {
data = d;
}
public Object pop() {
Object d = data;
data = null;
return d;
}
class Producer implements Runnable {
public void run() {
while (true) {
Object o = createNewObject();
push(o);
}
}
}
class Consumer implements Runnable {
public void run() {
while (true) {
Object o = pop();
doSomethingWith(o);
}
}
}
public static void main(String args[]) {
(new Thread(new Producer())).start();
(new Thread(new Consumer())).start();
}
The problem with these naive Producer and Consumer classes is that they have no way of cooperating with each other. If one thread is faster than the other, it should occasionally
wait for the slower thread to catch up. We can change the push() and pop() methods to take turns, so that one thread will not outstrip the other:
public void push(Object d) {
while (data != null) { /* Empty while--eats CPU. */ }
data = d;
}
public Object pop() {
while (data == null) { /* Empty. */ }
Object d = data;
data = null; /* Allow push() to break out of its loop.
*/
return d;
}
When one thread runs push() and another thread runs pop(), they keep in sync by means of the data field. push() waits for pop() by constantly checking the data field. When data becomes null, push() can assign a new object to it. pop() uses the same technique, sitting in a tight loop, waiting for data to change. When data becomes nonnull, pop() should return it and set it back to null.
That technique is called busy waiting, and it has a number of problems. One of the most serious drawbacks is that it can consume all the available CPU cycles. If
the consume() thread has an equal or higher priority than the produce() thread, consume()'s busy waiting can even prevent produce() from running!
Java obviates the need for busy waiting with monitors and wait sets. A monitor is a data structure that can hold only one
thread at a time. If a thread tries to enter a monitor that already holds a thread, the second thread will block until the
first leaves the monitor. Every object has a monitor: a thread enters it by calling a synchronized method on that object or
by entering a block of code that is synchronized on it. Every Java object also has a wait set -- a set of threads that sleep
until another thread tells the object to wake one of them up. A thread enters an object's wait set by calling wait() on that object. It can leave the wait set when another thread calls the object's notify() method.
Free Download - 5 Minute Product Review. When slow equals Off: Manage the complexity of Web applications - Symphoniq
![]()
Free Download - 5 Minute Product Review. Realize the benefits of real user monitoring in less than an hour. - Symphoniq