Name: joT67522 Date: 09/04/97
While writing a multi-threaded application, I switched data
structures from a Vector to a home grown linked list
implementation. This switch caused random segmentation faults
from the VM, which I traced as best as I could to the
markChildren() function in gc.c (no line number available).
I am running on a 2 processor SparcStation 10, Solaris 2.5.1,
with 64MB of RAM. I've seen the problem under both JDK 1.1.2
and 1.1.3, using green_threads. This problem was also seen
on 2 UltraSparcs and a SparcStation 20 (configurations unknown).
To reproduce the problem, compile the following 3 classes and
then run
java ThreadTest
Typical runs print out approximately 950 messages on my machine
before a segmentation fault occurs.
-- begin ThreadTest.java --
public class ThreadTest {
private static MessageList ml = new MessageList();
public static void main(String[] argv) {
new Writer(ml); // 1st writer
new Writer(ml); // 2nd writer
Object message;
while (true) {
synchronized(ml) {
while (ml.isEmpty()) {
try {
ml.wait();
} catch (InterruptedException ie) {
}
}
message = ml.firstElement();
}
System.out.println(message);
}
}
}
-- end ThreadTest.java --
-- begin MessageList.java --
public class MessageList {
class MessageElement {
MessageElement next;
Object data;
MessageElement(Object data) {
this.data = data;
}
}
private MessageElement first;
private MessageElement last;
/** Return true if the element is empty, false otherwise */
public boolean isEmpty() {
return first == null;
}
/** Add an element to the list */
public synchronized void addElement(Object data) {
MessageElement newElement = new MessageElement(data);
if (last == null) {
first = newElement;
} else {
last.next = newElement;
}
last = newElement;
}
/** remove the first element and return it */
public synchronized Object firstElement() {
Object returnValue = null;
// If the list isn't empty, then get the data value and move to the
// next element
if (!isEmpty()) {
returnValue = first.data;
first = first.next;
}
// if the list is now empty, then make sure the last element is
// set to null
if (isEmpty()) {
last = null;
}
return returnValue;
}
}
-- end MessageList.java --
-- begin Writer.java --
public class Writer extends Thread {
MessageList ml;
private static int writerNum;
private static synchronized int nextWriterNum() {
return writerNum++;
}
public Writer(MessageList ml) {
super("Writer-" + nextWriterNum());
this.ml = ml;
this.start();
}
private int messageNum;
public void run() {
while (true) {
synchronized(ml) {
boolean shouldNotify = ml.isEmpty();
ml.addElement(new String(getName() + ": message " +
messageNum++));
if (shouldNotify) ml.notifyAll();
}
}
}
}
-- end Writer.java --
company - Sun Microsystems/JavaSoft , email - ###@###.###
======================================================================