0

I have two Timers in java that are scheduled independently. Both timers have different Task.

Timer 1 increments a number and Timer 2 changes the period of Timer 1. Here is the code where I am using two timers

public class Receiver 
{ 
     public static int               totalBufferCapacity     = 1024; 
     public static int               totalPacketsDropped     = 0; 
     public static int               totalPacketsServiced    = 0; 
     public static int               totalPacketsReceived    = 0; 
     public static int               timesBufferGetsFull     = 0; 
     public static int               timesIntervelChanged    = 0; 

     public static Socket            clientSocket; 
     public static BufferedReader    br; 
     public static ArrayList<String>   buffer; 

     public static String            START                   = "Start"; 
     public static String            STOP                    = "Stop"; 
     public static String            token                   = "1"; 
     public static boolean           flag; 

     public static Timer             timer; 

     public static int               Max                     = 80; 
     public static int               Min                     = 40; 

     public static int               rand; 
     public static PrintStream       ps; 
     public static String            packet; 
     public static Timer             timer_2; 
     public static consumeArrayItems task; 


     public static void main(String[] args) 
    { 
        flag = true; 
        try
        { 
           init(args[0], args[1]); 

           while (flag) 
           { 
              storePacketInArray(); 
           } 

        } catch (Exception e) 
        { 
             e.printStackTrace(); 
        } 
    } 


    public static void init(String localHost, String portNumber) 
    { 
        try
        { 

            // inet address which is local host in this case 
            InetAddress acceptorHost = InetAddress.getByName(localHost); 

            // port number at which the sender wants to communicate 
            int serverPortNum = Integer.parseInt(portNumber); 

            clientSocket = new Socket(acceptorHost, serverPortNum); 

         } catch (IOException e) 
         { 
             e.printStackTrace(); 

         } 
    } 



     public static void storePacketInArray() 
     { 
          try
          { 
             if (br == null) 
             { 
                  br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
             } 

           packet = new String(br.readLine()); 

           if (packet.compareToIgnoreCase("Start") == 0) 
           { 
                 token = START; 
                 buffer = new ArrayList<String>(totalBufferCapacity); 
           } else if (packet.compareToIgnoreCase("Stop") == 0) 
           { 
                 stopVaryingTimeSchedular(); 
                 stopSchedular(); 
           } else
           { 
                 totalPacketsReceived += 1; 
                 buffer.add(packet); 
           } 


           computeToken(); 

        } catch (IOException e) 
        { 
            e.printStackTrace(); 

        } 
     } 


    public static void computeToken() 
    { 
        int bufferSize = buffer.size(); 

        if (bufferSize > 0 && bufferSize < totalBufferCapacity) 
        { 
             float queueOccupancy = (bufferSize * 100 / totalBufferCapacity); 


        } else if (bufferSize == totalBufferCapacity) 
        { 
             token = "10"; 
             timesBufferGetsFull += 1; 
        } else if (token.compareToIgnoreCase("Start") == 0) 
        { 
             token = START; 
             startSchedular(); 
             startVaryingTimeSchedular(); 

         } else
        { 
              totalPacketsDropped += 1; 
              token = "15"; 

        } 


        sendAcknowledgment(); 

     } 



     public static void sendAcknowledgment() 
    { 

         try
         { 
             if (ps == null) 
             { 
                 ps = new PrintStream(clientSocket.getOutputStream()); 
             } 

             String tokenAck = token; 

             if (packet.compareToIgnoreCase("Stop") != 0) 
             { 
                 ps.println(tokenAck); 
                 ps.flush(); 
             } 
             if (!flag) 
             { 
                 clientSocket.close(); 
             } 

         } catch (IOException e) 
         { 
              e.printStackTrace(); 
         } 

    } 


     public static void startSchedular() 
     { 

          rand = (int) (Math.random() * (Max - Min)); 
          timer = new Timer(); 
          task = new consumeArrayItems(true); 
          timer.scheduleAtFixedRate(task, 1, rand); 
     } 

     public static void stopSchedular() 
     { 
         timer.cancel(); 
         timer.purge(); 
         flag = false; 

     } 

      // After every 500 ms service time of packets will vary between Max and Min 
     public static void startVaryingTimeSchedular() 
     { 
         timer_2 = new Timer(); 
         timer_2.scheduleAtFixedRate(new varyServiceTime(), 0, 500); 
     } 

     public static void stopVaryingTimeSchedular() 
     { 

         timer_2.cancel(); 
         timer_2.purge(); 
     } 

  } 


 class consumeArrayItems extends TimerTask 
 { 


       public synchronized void run() 
       { 
          if (Receiver.buffer.size() > 0) 
          { 
              Receiver.totalPacketsServiced += 1; 
              Receiver.buffer.remove(Receiver.buffer.size() - 1); 
          } 
       } 
  } 

  class varyServiceTime extends TimerTask 
  { 

        public synchronized void run() 
        { 
              Receiver.timer.cancel(); 
              Receiver.timer = null; 
              Receiver.rand = (int) (Math.random() * (Receiver.Max - Receiver.Min)); 
              Receiver.timer = new Timer(); 
              Receiver.timer.scheduleAtFixedRate(new consumeArrayItems(), 0,Receiver.rand); 

              Receiver.timesIntervelChanged += 1; 
        } 
  } 

Timer 2 never gets scheduled. What wrong I am doing here.

Mehroze Yaqoob
  • 1,011
  • 1
  • 12
  • 29
  • 1
    Why do you think `timer_2` is never scheduled? How did you check this? – Dawood ibn Kareem Mar 09 '14 at 18:34
  • because timesIntervelChanged value is always 0 as I print its value – Mehroze Yaqoob Mar 09 '14 at 18:35
  • Can you show the code for the Receiver class? – Dawood ibn Kareem Mar 09 '14 at 18:38
  • 1
    You are incrementing a variable in one thread and reading in another. Presumably you are not synchronising anything. In any case, it's probably better to use a [`ScheduledExecutorService`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html) for your use case; you can stop tasks as restart them without stopping the service. – Boris the Spider Mar 09 '14 at 18:43
  • I have shared the major code here, remaining is just standard few methods doing array manipulation – Mehroze Yaqoob Mar 09 '14 at 18:43
  • Perhaps [Pausing/stopping and starting/resuming Java TimerTask continuously?](http://stackoverflow.com/questions/2098642/pausing-stopping-and-starting-resuming-java-timertask-continuously) helps? – Heinrich Mar 09 '14 at 19:07
  • As @BoristheSpider has obliquely pointed out, printing a variable from one thread and seeing it unchanged doesn't imply that you haven't changed it from another thread. Since you refuse to post the Receiver class, I can't tell whether this variable is volatile or not, but if you haven't marked it as volatile, there's no guarantee that you're seeing the latest value when you print it. – Dawood ibn Kareem Mar 09 '14 at 19:41
  • @DavidWallace I have posted the whole Receiver Class. I have also noticed that I got null pointer exception at timer although I initialised timer as Receiver.timer = new timer(). So I think what you are saying about volatile may be the cause but not sure. – Mehroze Yaqoob Mar 10 '14 at 05:00
  • The thing I most wanted to see was your field declarations, but you seem to have omitted them. – Dawood ibn Kareem Mar 10 '14 at 05:12
  • @DavidWallace I included them now as well – Mehroze Yaqoob Mar 10 '14 at 05:17
  • @DavidWallace The main region where I suspect root cause the varyService Class where I change the period of first timer. – Mehroze Yaqoob Mar 10 '14 at 05:20
  • OK, so most of those fields need to be `volatile`. I suspect that your code IS in fact doing what you expect, but when you're printing it, you're not seeing the change, because of some kind of caching optimisation. – Dawood ibn Kareem Mar 10 '14 at 05:23
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/49371/discussion-between-lion-heart-and-david-wallace) – Mehroze Yaqoob Mar 10 '14 at 05:59
  • @Heinrich you are a gem buddy – Mehroze Yaqoob Mar 10 '14 at 19:49

0 Answers0