Z
Zoo 9000
I've been trying to understand how wait() and notify() work
but even Sun's own explanation (here,
http://java.sun.com/products/jdk/1.2/docs/guide/misc/threadPrimitiveDeprecation.html
) isn't clear and doesn't give a working example.
So I've tried to build a simple one myself. The program (below)
compiles and runs under J2SE 1.4.1 but throws an
'IllegalMonitorStateException' (whatever that is..). If anyone can
show me where I'm going wrong I'd be grateful.
- Ken
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class VisualWaitNotify
extends JPanel
implements Runnable {
private static final String[] symbolList =
{ "|", "/", "-", "\\", "|", "/", "-", "\\" };
private Thread runThread;
private JTextField symbolTF;
private boolean threadSuspended = false;
public VisualWaitNotify() {
symbolTF = new JTextField();
symbolTF.setEditable(false);
symbolTF.setFont(new Font("Monospaced",
Font.BOLD, 26));
symbolTF.setHorizontalAlignment(JTextField.CENTER);
final JButton waitB = new JButton("Wait");
final JButton notifyB = new JButton("Notify");
waitB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
waitNow();
}
});
notifyB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
notifyNow();
}
});
JPanel innerStackP = new JPanel();
innerStackP.setLayout(new GridLayout(0, 1, 3, 3));
innerStackP.add(symbolTF);
innerStackP.add(waitB);
innerStackP.add(notifyB);
this.setLayout(new FlowLayout(FlowLayout.CENTER));
this.add(innerStackP);
}
private void waitNow() {
threadSuspended = true;
try {
synchronized (this) {
while (threadSuspended)
runThread.wait();
}
} catch (InterruptedException e){
}
}
private synchronized void notifyNow() {
threadSuspended = false;
if ( runThread != null ) {
runThread.notify();
}
}
public void run() {
try {
runThread = Thread.currentThread();
int count = 0;
while ( true ) {
// each time through, show the next symbol
symbolTF.setText(
symbolList[ count % symbolList.length ]);
Thread.sleep(200);
count++;
}
} catch ( InterruptedException x ) {
// ignore
} finally {
// The thread is about to die, make sure
// that the reference to it is also lost.
runThread = null;
}
}
public static void main(String[] args) {
VisualWaitNotify vwn = new VisualWaitNotify();
Thread t = new Thread(vwn);
t.start();
JFrame f = new JFrame("Visual Wait and Notify");
f.setContentPane(vwn);
f.setSize(320, 200);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
but even Sun's own explanation (here,
http://java.sun.com/products/jdk/1.2/docs/guide/misc/threadPrimitiveDeprecation.html
) isn't clear and doesn't give a working example.
So I've tried to build a simple one myself. The program (below)
compiles and runs under J2SE 1.4.1 but throws an
'IllegalMonitorStateException' (whatever that is..). If anyone can
show me where I'm going wrong I'd be grateful.
- Ken
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class VisualWaitNotify
extends JPanel
implements Runnable {
private static final String[] symbolList =
{ "|", "/", "-", "\\", "|", "/", "-", "\\" };
private Thread runThread;
private JTextField symbolTF;
private boolean threadSuspended = false;
public VisualWaitNotify() {
symbolTF = new JTextField();
symbolTF.setEditable(false);
symbolTF.setFont(new Font("Monospaced",
Font.BOLD, 26));
symbolTF.setHorizontalAlignment(JTextField.CENTER);
final JButton waitB = new JButton("Wait");
final JButton notifyB = new JButton("Notify");
waitB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
waitNow();
}
});
notifyB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
notifyNow();
}
});
JPanel innerStackP = new JPanel();
innerStackP.setLayout(new GridLayout(0, 1, 3, 3));
innerStackP.add(symbolTF);
innerStackP.add(waitB);
innerStackP.add(notifyB);
this.setLayout(new FlowLayout(FlowLayout.CENTER));
this.add(innerStackP);
}
private void waitNow() {
threadSuspended = true;
try {
synchronized (this) {
while (threadSuspended)
runThread.wait();
}
} catch (InterruptedException e){
}
}
private synchronized void notifyNow() {
threadSuspended = false;
if ( runThread != null ) {
runThread.notify();
}
}
public void run() {
try {
runThread = Thread.currentThread();
int count = 0;
while ( true ) {
// each time through, show the next symbol
symbolTF.setText(
symbolList[ count % symbolList.length ]);
Thread.sleep(200);
count++;
}
} catch ( InterruptedException x ) {
// ignore
} finally {
// The thread is about to die, make sure
// that the reference to it is also lost.
runThread = null;
}
}
public static void main(String[] args) {
VisualWaitNotify vwn = new VisualWaitNotify();
Thread t = new Thread(vwn);
t.start();
JFrame f = new JFrame("Visual Wait and Notify");
f.setContentPane(vwn);
f.setSize(320, 200);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}