img
.
If you use an iterator, you must use it entirely within a synchronized block or else another thread
might change the collection while the iterator is using it (Code Example 11-5)
Example 11-5 Protecting an Iterator
synchronized (syncdList) {
Iterator i = syncdList.iterator();
while (i.hasNext())
foo(i.next());
}
Java's Multithreaded Garbage Collector
Obviously, Java's garbage collector must work in a threaded environment. There are a number of
different algorithms that will do this. They range from simple stop-and-copy garbage collectors to
realtime, dynamic, generational collectors. As Java is very specifically not a realtime language,
stop-and-copy is perfectly acceptable. The actual algorithm used is not specified by Java, and
different implementations use different collectors.
By the very nature of garbage collection, a multithreaded garbage collector is significantly more
complex than a single-threaded collector. In a single-threaded collector, the system is able to run
freely until it runs out of heap, in which case it can then run a GC directly. As there is only one
thread, that thread is clearly in a known safe state and the GC can proceed immediately. In a
multithreaded collector, things are not so simple.
In an MT environment, when a thread discovers that it needs to start a GC, it cannot just begin
immediately. There are more threads out there and they must not be allowed to interfere. First,
they must not be allowed to use the heap while our GC thread is changing it. Second, they must
not be allowed to change any pointers while the GC thread is running. Third, the entire state of the
system must be consistent and all internal invariants correct.
This is accomplished by requiring all other threads to arrive at a known safe place in the JVM and
stay there. How to get all the threads to do this is another matter, and there are plenty of clever
schemes used to ensure all threads arrive at one of the GC points as quickly as possible.
Now, can your GC also compact the heap? And do you want it to? Yes, the GC can compact the
heap. It's a little bit tricky if you hash on an address, but possible. In some set of programs,
compacting will allow you to run in a smaller memory machine. But outside of intentionally
mistuned programs, this probably isn't an issue anyway. Memory is plentiful and cheap.
Locks during Finalization
As with all finalization, you never know if or when it is going to happen. Trying to lock locks
during finalization can easily get a naively written program into a deadlock. What do you want to
use finalization for anyway? There is almost certainly a better way to do whatever you're thinking
about.
Summary
Search WWH :
Custom Search
Previous Page
Multithreaded Programming with JAVA - Topic Index
Next Page
Multithreaded Programming with JAVA - Bookmarks
Home