5 Replies Latest reply: Nov 23, 2006 7:19 PM by 807607 RSS

    A problem with synchronizing threads.

    807607
      Hello, I have some code listed below. Eventually I will have 4 threads, 3 of which will make up a counter (hours, minutes, seconds).

      At the moment I simply wish to get some functionality from my program before making it more complex. I am trying to pass a value ("Test String") into a JLabel and have set up a synchronized block that takes the argument and updates the field. This block has a boolean condition controlled by the controller, ever second this is set to true.

      The problem I am having is that none of the threads are updating the screen. I have tried system.out to test and they are getting to the wait block but no further.

      Can anyone spot what I am doing wrong. For now I will just post the main class, I can supply the other 3 if you like but I feel the problem lies with this one.
      import java.awt.FlowLayout;
      import javax.swing.*;
      
      
      public class ClockDisplay
      {
           private int hours = 0;
           private int minutes =0;
           private int seconds = 0;
           boolean okToSend=false;
           private JFrame myFrame = new JFrame();
           private JTextField textField = new JTextField(8);
           
           private ClockDisplay() 
           {
      
           }
           public void startUp()
           {
                myFrame.setLayout(new FlowLayout());
                myFrame.add(textField);
                myFrame.setSize(300, 300);
                myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                myFrame.setVisible(true);
           }
           
           public synchronized void changeText(String s)
           {
                boolean okToSend = false;
      
               try
               {
                      while(!okToSend)
                      {
                         System.out.println(s); //ignore
                        wait();
                      } 
                           okToSend = false;
                           textField.setText(s);
               }
               catch(InterruptedException ex){}
            }
      
           public synchronized void allowOutput() // Sys outs show the controller enters here
           {
              okToSend = true;
              notify();
           }
           
           //Singleton Class
           private static class SingletonHolder 
           {
                private static ClockDisplay instance = new ClockDisplay();
           }
      
           public static ClockDisplay getInstance() 
           {
                return SingletonHolder.instance;
           }
      }
      Cheers

      Mike
        • 1. Re: A problem with synchronizing threads.
          807607
          its a scope problem you define
          boolean okToSend = false;
          in your method, which you should be
          • 2. Re: A problem with synchronizing threads.
            807607
            do'h, silly me. Thanks!

            Mike
            • 3. Re: A problem with synchronizing threads.
              807607
              Hello again.

              I am having some more trouble with threads. I have a start class and a threads class as well as the one below. The start class creates 3 new threads from the the threads class and deploys them on the class below. The problem I am having is that the seconds counter dosent get passed 3. The threads are locking in some way and I cant work out how.

              My code is below, can anyone spot what I am doing wrong?
              package com.mk.clock;
              
              import java.awt.FlowLayout;
              import javax.swing.*;
              
              
              public class ClockDisplay
              {
                   private int hours = 0;
                   private int minutes =0;
                   private int seconds = 0;
                   boolean okToSend3;
                   boolean okToSend2;
                   boolean okToSend1;
                   private JFrame myFrame = new JFrame();
                   private JTextField textField1 = new JTextField(2);
                   private JTextField textField2 = new JTextField(2);
                   private JTextField textField3 = new JTextField(2);
                   
                   private ClockDisplay() 
                   {
              
                   }
                   public void startUp()
                   {
                        myFrame.setLayout(new FlowLayout());
                        myFrame.add(textField1);
                        myFrame.add(textField2);
                        myFrame.add(textField3);
                        myFrame.setSize(300, 300);
                        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                        myFrame.setVisible(true);
                   }
                   
                   public synchronized void changeText()
                   {
                        try
                       {
                               Thread.sleep(1000);
                               seconds++;
                               textField3.setText(String.valueOf(seconds));
                               System.out.println(seconds);
                              
                               if (seconds >59)
                                  {
                                       seconds=0;
                                       allowUpdateT2();
                                  }
                       }
                       catch(InterruptedException ex){}
                       
                        try
                       {
                              while(!okToSend2)
                              {
                                wait();
                              } 
                              textField2.setText(String.valueOf(minutes++));
                              okToSend2=false;
                              
                              if(minutes >59)
                              {
                                   minutes=0;
                                   allowUpdateT1();
                              }
                       }
                       catch(InterruptedException ex){}
                  
                       try
                       {
                              while(!okToSend1)
                              {
                                wait();
                              } 
                              textField1.setText(String.valueOf(hours++));
                              okToSend1=false;
                       }
                       catch(InterruptedException ex){}
                   }
                   
                   
                   public synchronized void allowUpdateT3()
                   {
                      okToSend3 = true;
                      notify();
                   }
                   public synchronized void allowUpdateT2()
                   {
                      okToSend2 = true;
                      notify();
                   }
                   
                   public synchronized void allowUpdateT1()
                   {
                      okToSend1 = true;
                      notify();
                   }
                   
                   
                   //Singleton Class
                   private static class SingletonHolder 
                   {
                        private static ClockDisplay instance = new ClockDisplay();
                   }
              
                   public static ClockDisplay getInstance() 
                   {
                        return SingletonHolder.instance;
                   }
              }
              I deploy the threads on the "change text" method. I know I could create 3 different methods for each textbox and 3 different thread classes for each textbox but surely there is an easier way.

              Any help would be great.

              Mike

              p.s. do i need 3 different try/catch blocks our could I use one for all text boxes?

              .
              • 4. Re: A problem with synchronizing threads.
                807607
                here si sthe rest of my code;
                public class ThreadClock 
                {
                     static ClockDisplay cd = ClockDisplay.getInstance();
                     
                     public static void main(String[] args)
                     {
                          Thread h = new Thread(new WorkerThread("hours"));
                          Thread m = new Thread(new WorkerThread("minutes"));
                          Thread s = new Thread(new WorkerThread("seconds"));
                          
                          cd.startUp();
                          s.start();
                          m.start();
                          h.start();
                     }
                }
                and
                public class WorkerThread implements Runnable
                {
                     static ClockDisplay cd = ClockDisplay.getInstance();
                     String name;
                     
                     public WorkerThread(String name)
                     {
                          this.name = name;
                     }
                     public void run() 
                     {
                          cd.changeText();
                     }
                
                }
                can anyone give me some sort of advice, even if its "fuck off"?
                • 5. Re: A problem with synchronizing threads.
                  807607
                  I didnt look up your code but you should take in consideration that most swing components are not thread safe and JTextField is one of them, if your are updating the text fields from multiple threads then you should use one of the following static methods of these classes
                   EventQueue.invokeLater(Runnable)
                   SwingUtilities.invokeLater(Runnable)
                  Check the API for details.

                  Regars
                  Andreas