// thread1
sig1.wait();
// thread2
sig2.wait();
// thread3
sig1.notify();
================or =============
class sigStruct {
String name;
}
// thread1
do { try{
sig.wait();
}catch(Exception e){}
while(!sig.name.equals("thread1"));// thread2
do { try{
sig.wait();
}catch(Exception e){}
while(!sig.name.equals("thread2"));// thread3
sig.name="thread1";
sig.notify();没有该书,另外的问题不能回答.
sig1.wait();
// thread2
sig2.wait();
// thread3
sig1.notify();
================or =============
class sigStruct {
String name;
}
// thread1
do { try{
sig.wait();
}catch(Exception e){}
while(!sig.name.equals("thread1"));// thread2
do { try{
sig.wait();
}catch(Exception e){}
while(!sig.name.equals("thread2"));// thread3
sig.name="thread1";
sig.notify();没有该书,另外的问题不能回答.
我用了thread1.notify(),但运行的时候出现错误,提示:
Exception occurred during event dispatching:
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.notify(Native Method)
at RandomCharacters.actionPerformed(RandomCharacters.java:111)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:14
45)
at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(Abstra
ctButton.java:1499)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel
.java:373)
at javax.swing.JToggleButton$ToggleButtonModel.setPressed(JToggleButton.
java:263)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonL
istener.java:211)
at java.awt.Component.processMouseEvent(Component.java:3710)
at java.awt.Component.processEvent(Component.java:3539)
at java.awt.Container.processEvent(Container.java:1159)
at java.awt.Component.dispatchEventImpl(Component.java:2588)
at java.awt.Container.dispatchEventImpl(Container.java:1208)
at java.awt.Component.dispatchEvent(Component.java:2492)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:2451
)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:2216) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:2125)
at java.awt.Container.dispatchEventImpl(Container.java:1195)
at java.awt.Component.dispatchEvent(Component.java:2492)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:334)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:126)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:93)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:88)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:80)
// Demonstrating the Runnableinterface
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;public class RandomCharacters extends JApplet
implements Runnable,
ActionListener {
private String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private JLabel outputs[];
private JCheckBox checkboxes[];
private final static int SIZE = 3;
private Thread threads[];
private boolean suspended[]; public void init()
{
outputs = new JLabel[ SIZE ];
checkboxes = new JCheckBox[ SIZE ];
threads = new Thread[ SIZE ];
suspended = new boolean[ SIZE ]; Container c = getContentPane();
c.setLayout( new GridLayout( SIZE, 2, 5, 5 ) ); for ( int i = 0; i < SIZE; i++ ) {
outputs[ i ] = new JLabel();
outputs[ i ].setBackground( Color.green );
outputs[ i ].setOpaque( true );
c.add( outputs[ i ] ); checkboxes[ i ] = new JCheckBox( "Suspended" );
checkboxes[ i ].addActionListener( this );
c.add( checkboxes[ i ] );
}
} public void start()
{
// create threads and start every time start is called
for ( int i = 0; i < threads.length; i++ ) {
threads[ i ] =
new Thread( this, "Thread " + (i + 1) );
threads[ i ].start();
}
} public void run()
{
Thread currentThread = Thread.currentThread();
int index = getIndex( currentThread );
char displayChar; while ( threads[ index ] == currentThread ) {
// sleep from 0 to 1 second
try {
Thread.sleep( (int) ( Math.random() * 1000 ) ); synchronized( this ) {
while ( suspended[ index ] &&
threads[ index ] == currentThread )
wait();
}
}
catch ( InterruptedException e ) {
System.err.println( "sleep interrupted" );
}
displayChar = alphabet.charAt(
(int) ( Math.random() * 26 ) );
outputs[ index ].setText( currentThread.getName() +
": " + displayChar );
} System.err.println(
currentThread.getName() + " terminating" );
} private int getIndex( Thread current )
{
for ( int i = 0; i < threads.length; i++ )
if ( current == threads[ i ] )
return i; return -1;
} public synchronized void stop()
{
// stop threads every time stop is called
// as the user browses another Web page
for ( int i = 0; i < threads.length; i++ )
threads[ i ] = null; notifyAll();
} public synchronized void actionPerformed( ActionEvent e )
{
for ( int i = 0; i < checkboxes.length; i++ ) {
if ( e.getSource() == checkboxes[ i ] ) {
suspended[ i ] = !suspended[ i ]; outputs[ i ].setBackground(
!suspended[ i ] ? Color.green : Color.red ); if ( !suspended[ i ] )
notify(); return;
}
}
}
}/**************************************************************************
* (C) Copyright 1999 by Deitel & Associates, Inc. and Prentice Hall. *
* All Rights Reserved. *
* *
* DISCLAIMER: The authors and publisher of this book have used their *
* best efforts in preparing the book. These efforts include the *
* development, research, and testing of the theories and programs *
* to determine their effectiveness. The authors and publisher make *
* no warranty of any kind, expressed or implied, with regard to these *
* programs or to the documentation contained in these books. The authors *
* and publisher shall not be liable in any event for incidental or *
* consequential damages in connection with, or arising out of, the *
* furnishing, performance, or use of these programs. *
*************************************************************************/
<applet code="RandomCharacters.class" width=275 height=90>
</applet>
</html>
The key is the term "monitor".
When a thread is waiting, it's waiting on a monitor.
A monitor is an Object which the "synchronized" keyword is used on.
notify() method(s) will wake up the thread or threads which has/have been put to wait or sleep.
Notice here: notify is called through the Monitor, not the thread.
The difference between notify and notifyAll is one wakes one thread randomly, the other wakes all up.
If an Object is not a "monitor" but the notify method is called, the IllegalMonitorStateException will be thrown.
For more information, email me at [email protected]
sig.notify();
}
public void run()
{
Thread currentThread = Thread.currentThread();
int index = getIndex( currentThread );
char displayChar; while ( threads[ index ] == currentThread ) {
// sleep from 0 to 1 second
try {
// Thread.sleep( (int) ( Math.random() * 1000 ) ); if ( suspended[ index ] &&
threads[ index ] == currentThread ){
System.out.println((index==0?" ":
index==1?" ":
" ")+"zzzzzzzz");
synchronized(currentThread) {
currentThread.wait();
}
System.out.println((index==0?" ":
index==1?" ":
" ")+"--------");
}
}
catch ( InterruptedException e ) {
// System.err.println( "sleep interrupted" );
System.out.println((index==0?" ":
index==1?" ":
" ")+"++++++++++");
} displayChar = alphabet.charAt(
(int) ( Math.random() * 26 ) );
outputs[ index ].setText( currentThread.getName() +
": " + displayChar );
} System.err.println(
currentThread.getName() + " terminating" );
} public void actionPerformed( ActionEvent e )
{
for ( int i = 0; i < checkboxes.length; i++ ) {
if ( e.getSource() != checkboxes[ i ] )
continue;
suspended[ i ] = ((JCheckBox)e.getSource()).isSelected();
outputs[ i ].setBackground(suspended[ i ] ? Color.red : Color.green ); if ( suspended[ i ] )
return;
synchronized(threads[i]) {
threads[i].notify();
}
return;
}
}