如题,底下是一段代码,synthronized( randomCharacter.this )说出错了,而且GUI无法更新,找不出问题出在哪里,请高手指教~~~! // randomCharacter.java
// A program Demostrating Runnable interface.
// Author:conanin
// setup time: May. 16th,2006import java.awt.*;
import java.awt.event.*;
import javax.swing.*;public class randomCharacter extends JApplet implements ActionListener
{
    //declare variable used by applet and inner class RunnableObject
    private String alphbet = " conaninandsarah ";
    private final static int size = 3;
    
    private JLabel outputs[];
    private JCheckBox checkBoxes[];
    
    private Thread threads[];
    private boolean needSuspend[];
    
    //set up GUI and arrays
    public void init()
    {
        outputs = new JLabel[ size ];
        checkBoxes = new JCheckBox[ size ];
    
        threads = new Thread[ size ];
        needSuspend = new boolean[ size ];
        
        Container c = getContentPane();
        c.setLayout( new GridLayout( size,2,5,5) );
        
        //create GUI component,register Listener and attach component to
        //Content pane.
        for( int count = 0; count<size; count ++ )
        {
         outputs[ count ] = new JLabel();
         outputs[ count ].setBackground( Color.GREEN );
         outputs[ count ].setOpaque( true );
        
         c.add( outputs[ count ] );
        
         checkBoxes[ count ] = new JCheckBox( "Suspend" );
         checkBoxes[ count ].addActionListener( this );
         c.add( checkBoxes[ count ] );       
        }
    }
    
    //Create and start Thread,this method called after init and when user 
    //revists Web Page containing this applet.
    public void start()
    {
     for( int count = 0 ; count < threads.length ; count ++ )
     {
     threads[ count ] = new Thread( new RunnableObject(),
     " thread " + ( count + 1) );
    
     threads[ count ].start();
     }
    }
    
    
    //determine thread location in threads array.
    private int getIndex( Thread current )
    {
     for( int count = 0 ; count < threads.length ; count ++ )
     {
     if( current ==  threads[ count ] )
     {
     return count;
     }
     }
    
     return -1;
    }
    
    // called when user switches Web Pages;stop all thread
    public synchronized void stop()
    {
     //indicate that all the threads should terminate.setting this 
     //refrence to null causes each thread's run method to complete
     //execution.
     for( int count = 0 ;count < threads.length ; count ++ )
     {
     threads[ count ] = null;
     }
    
     //make all waiting thread ready to execute,so they can terminate 
     //themselves.
     notifyAll();
    }
    
    //handle button event
    public synchronized void actionPerformed( ActionEvent e )
    {
     for( int count = 0 ; count < checkBoxes.length ; count ++ )
     {
     if( e.getSource() == checkBoxes[ count ] )
     {
     needSuspend[ count ] = !needSuspend[ count ];
    
     //change label color on suspend/resume.
     outputs[ count ].setBackground( 
     !needSuspend[ count ]?Color.GREEN:Color.RED );    
     //if thread resume,make sure it start execution.
       if( !needSuspend[ count ] )
     {
     notifyAll();
     }
    
     return;
     }
     }
    }
    
    //private inner class that implements interface Runnable so 
    //objects of this class can control thread.
    private class RunnableObject implements Runnable
    {
     //place random characters in GUI.Local variable currentThread and
     //index are declared final so they can used in anonymous inner class.
     public void run()
     {
     //get reference to executing thread.
     final Thread currentThread = Thread.currentThread();
         
     //determine thread location in threads array.
     final int index = getIndex( currentThread );
         
         //loop condition determine when thread should stop.
     while( threads[ index ] == currentThread )
         {
          try
          {
          //sleep from 0 to 1 second
          threads[ index ].sleep( Math.random() * 1000 );
         
          //determine whether thread should suspend execution.
          //use applet as moniter.
          synthronized( randomCharacter.this )
          {
          while( needSuspend[ index ] && threads[ index ] == currentThread )
          {
          //temperorily stop thread execution.use applet as moniter.
          RandomCharacter.this.wait();
          }
          }    //end synchronized block.
          }
         
          //process InterrupttedException when thread sleep or wait.
          catch( InterrupttedException interrupttedException )
          {
          System.err.print( "Sleep interrupted" );
          }
         
          //display character on corresponding label.
          SwingUtilities.invokeLater
          (
          //anonymous inner class used by SwingUtilities method
          //invokeLater to ensure GUI update correctly.
          new Runnable()
          {
          //update Swing GUI Component.
          public void run()
          {
          //pick random character.
          Char displayChar = alphbet.charAt
          ( ( int )( Math.random() * 26 ));
                   
              outputs[ index ].setText( currentThread.getName() + 
          ": " + displayChar() );
          }
          }
          );  //end of anonymous inner class 
         }  //end call to SwingUtilities method invokeLater.
    
         System.err.println( current.getName() + " terminating ");
     }
    }
}