Results 1 to 19 of 19
  1. #1
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default ScheduledThreadPoolExecutor is losing tasks

    I got the start of this program from: https://coderanch.com/t/682689/java/...aphical-Object
    and was working on another approach using ScheduledThreadPoolExecutor. However the code is losing scheduled tasks. I have run out of ideas so I'm posting it here for others that might be interested. Changing the nbrBalls variable changes the number of lost tasks.
    The original project was using a thread for each ball. At some point there aren't enough threads available. The code displays and moves 4000 balls with the single thread of the ScheduledThreadPoolExecutor BUT it stops moving some balls. Why???
    Java Code:
    /* https://coderanch.com/t/682689/java/Animated-Multi-Thread-Graphical-Object
    
    Note: Added executor ->>> Problem: loses tasks???
    */
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.*; //Graphics2D;
    import java.util.ArrayList;
    import java.util.*; //List;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import java.util.concurrent.*;
    
     
    /*
     * Demo: Draw some things where each thing changes its state in its own thread.
     * @author Brian Cole
     */
    @SuppressWarnings("serial")
    
    public class Dodunski {
    
        ScheduledThreadPoolExecutor executor;
        int width = 900;
        int height = 700;
        int nbrBalls = 50;           // loose movements with 100    / 2 unmoved with 50  / no unmoved with 30
     
        public static void main(String[] argv) {
    //       System.out.println("main thread="+Thread.currentThread());    // main thread=Thread[main,5,main]     
           SwingUtilities.invokeLater( () -> new Dodunski().startup() );
        }
     
        public void startup() {
    //        System.out.println("startup thread="+Thread.currentThread()); // startup thread=Thread[AWT-EventQueue-0,6,main]
            JFrame frame = new JFrame("Harbor");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            executor =  new ScheduledThreadPoolExecutor(1);       //<<<<<<< do all on one thread?   same with 4 ???
            frame.setContentPane(new Harbor());
            frame.setSize(width, height);
            frame.setVisible(true);
        }
    
        // See if synchronized is the cause of losing tasks >>>> No change, still loses tasks
        synchronized void doSchedule(Callable<String> ball, long time) {
            ScheduledFuture<String> sf = executor.schedule(ball, time, TimeUnit.MILLISECONDS);
            if(sf.getDelay(TimeUnit.MILLISECONDS) <= 0) {
              System.out.println(sf.getDelay(TimeUnit.MILLISECONDS));     //NEVER
            }
        }
    
        //====================================================================
        public class Harbor extends JComponent {
            private java.util.List<BallWithOwnThread> balls = new ArrayList<>();
                Random ran = new Random();
     
            public Harbor() {                //              x   y   rad dx dy ms   blnk         start
                balls.add( new BallWithOwnThread(Color.BLUE, 32, 64, 12, 1, 2, 101, false, this, true) );
                balls.add( new BallWithOwnThread(Color.GREEN, 32, 32, 12, 2, 1, 227, true, this, true) );
    
                // add a bunch with own threads      >> CPU usage 40% 
                for(int i=0; i < 0; i++) {      // java.lang.OutOfMemoryError: unable to create new native thread  w/4000 
                   int x = ran.nextInt(width);
                   int y = ran.nextInt(height);
                   int dx = (x > width/2) ? -2 : 2;  // different directions depending on starting loc
                   int dy = (y < height/2 ? 1 : -1);
                   int speed = 100 + ran.nextInt(300);
                   Color aColor = new Color(x%255, y%255,ran.nextInt(255));
                   balls.add( new BallWithOwnThread(aColor, x, y, 12, dx, dy, speed, false, this, true) );
                }
    
                // define some to use one thread with executor   >>  CPU usage  40%
                BallWithOwnThread bwot = null;
                long start = 0L;
                for(int i=0; i < nbrBalls; i++) {
                   int x = ran.nextInt(width);
                   int y = ran.nextInt(height);
                   int dx = (x > width/2) ? -2 : 2;  // different directions depending on starting loc
                   int dy = (y < height/2 ? 1 : -1);
                   int speed = 100 + ran.nextInt(300);
                   Color aColor = new Color(x%255, y%255,ran.nextInt(255));
                   balls.add(bwot = new BallWithOwnThread(aColor, x, y, 12, dx, dy, speed, false, this, false) );
                   executor.schedule((Callable<String>)bwot, start++, TimeUnit.MILLISECONDS);
                }
    
                //- - - - - - - - - - - - - - - - - - - - 
                System.out.println("starting Q size="+ executor.getQueue().size());   // starting Q size=4000
    
                //  Some balls are not moving >>> Try to find them???
                Thread t = new Thread(new Runnable() {
                   public void run() {
                      while(true) {
                         try{Thread.sleep(5000);}catch(Exception x){}
                         int cnt = 0;
                         for(BallWithOwnThread bwot : balls) {
                            if(!bwot.checkMoved())  {
                               cnt++;
                            }
                         }
                         System.out.println("Q size="+ executor.getQueue().size() +", unmoved balls = "+cnt);
                         //     Some stop moving after a bit???
                         /*
                         Q size=3960, unmoved balls = 0
                         Q size=3894, unmoved balls = 60
                         Q size=3795, unmoved balls = 113
                         Q size=3733, unmoved balls = 205
                         Q size=3647, unmoved balls = 275
    
                          ballId=28 java.awt.Point[x=148,y=575] moveCnt=274    <<  This ball was not moving
    
                         */
                      }
                   }
                });
                t.start();
    
                // MouseListener to allow seletion of a ball
                addMouseListener(new javax.swing.event.MouseInputAdapter() {
                   @Override
                   public void mousePressed(java.awt.event.MouseEvent me) {
    //                  System.out.println("mP at="+me.getPoint());
                      for(BallWithOwnThread bwot : balls) {
                            if(bwot.onBall(me.getPoint()))  {
                               System.out.println("ballId="+bwot.ballId + " " +bwot.getLocation() + " moveCnt="+bwot.movedCnt);
                            }
                      }
    
                   }
                });
            }    // end constructor
     
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g); // handle opaqueness
                Graphics2D g2 = (Graphics2D)g;
                balls.forEach( ball -> ball.paint(g2) );   //??? don't call if not moved!!!
            }
        } // end static class Harbor
    
        //---------------------------------------------------------------
        //  Fields for saving delay times
        static int[] delays = new int[21];  // hold 1-20 and > 20
        static int cntr = 0;
    
        static int id = 0;    //  to give ball objects unique ids
     
        /*  ====================================================================================
         * Few of us would argue that each Ball should have its own thread,
         * especially if there are going to be a large number of balls, but
         * this is a proof-of-concept that the approach can work.
         */
        public  class BallWithOwnThread implements Runnable, java.util.concurrent.Callable<String> {
            private Color color;
            private volatile int x, y; 
            int radius, dx, dy, milliseconds;
            private boolean blink, 
                            visible=true;
            private JComponent parent;
    
            private boolean moved = true;   // to record when paint called w/o a move being done
            int ballId = id++;
    
            public volatile int movedCnt = 0;   // to detect if any balls are not moved >>> all are moving ???
     
            public BallWithOwnThread(Color color, int x, int y, int radius, int dx,
                      int dy, int milliseconds, boolean blink, JComponent parent, boolean startThread) {
                this.color = color;
                this.x = x;
                this.y = y;
                this.radius = radius;
                this.dx = dx;
                this.dy = dy;
                this.milliseconds = milliseconds;
                this.blink = blink;
                this.parent = parent;
                // create and start this object's thread
                if(startThread)   {                //<<<<<<<<
                   new Thread(this).start();
                }
            }
     
            public boolean onBall(Point p) {
                return (p.x > x-radius) && (p.x < x+radius)
                       && (p.y > y-radius) && (p.y < y+radius); 
            }
            public Point getLocation() {
               return new Point(x,y);
            }
    
            public void paint(Graphics2D g) {
    //            if(!moved)  return; //<<<<<<<    makes for poor drawing when balls cross paths
    //            System.out.println("thread="+Thread.currentThread());  // thread=Thread[AWT-EventQueue-0,6,main]    
                // Draw the ball. Don't change state.
                if (visible) {
                    g.setColor(color);
                    g.fillOval(x-radius, y-radius, 2*radius, 2*radius);
                }
                if(moved) {
                  moved = false;
                }else {
    //               System.out.println("paint called w/o move "+ballId);   //<<<<<<<<<<<<
                }
            }
    
            //---------------------------------------------------------
            long lastCall = 0L;     // to compute delays
    
            @Override
            public String call() {
               long currTime = System.currentTimeMillis();
               if(lastCall != 0) {
                  int delay = (int)(currTime - lastCall); 
                  delay -= milliseconds;
                  if(delay < delays.length) delays[delay]++;
                  else delays[delays.length-1]++;
                  if(delay >  2) { // only show some
    //                  System.out.println(">>>>>>delayed "+ delay + " vs " + milliseconds);
                      if(cntr++ % 30 == 0)  {   // only show some
    //                     System.out.println("cntr="+cntr + " " +java.util.Arrays.toString(delays));
                      }
                         // cntr=51 [0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0]      ???? only 3 ????
                         // cntr=271 [0, 0, 0, 163, 35, 21, 19, 13, 6, 2, 12]
                         // cntr=61 [38856, 28784, 5379, 49, 1, 3, 2, 1, 0, 0, 5]
                         // cntr=181 [84624, 58662, 9812, 154, 7, 2, 1, 1, 2, 4, 10]
                         // cntr=331 [171433, 104896, 15056, 310, 0, 1, 0, 1, 0, 3, 16]
                         // cntr=15601 [184753, 112444, 16948, 1147, 875, 648, 598, 516, 526, 466, 518, 460, 463, 467, 483, 465, 511, 446, 516, 495, 6001]
                  }
               }
               lastCall = currTime;      // save for delay comps
    
               moveIt();   
                                          
               // schedule next move
               doSchedule(this, milliseconds);          // see if synch keeps from losing balls from queue??? DID NOT Help
    //           executor.schedule((Callable<String>)this, milliseconds, TimeUnit.MILLISECONDS);
    //           System.out.println("thread="+Thread.currentThread());      // thread=Thread[pool-1-thread-1,5,main]
               return "";           //????
            }
     
            //-------------------------------------------------
            @Override
            public void run() {
    //            System.out.println("run thread="+Thread.currentThread());  
                // run thread=Thread[Thread-2,6,main] 
                // run thread=Thread[Thread-1,6,main]
                // ...
                // run thread=Thread[Thread-100,6,main]
    
                // Change state in a loop.
                for ( ; ; ) {
                    // Again, Thread.sleep() is probably not the best approach but,
                    // since we decided to go that way, it does actually work.
                    try {
                        Thread.sleep(milliseconds);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        return;
                    }
                    moveIt();
                }
            }
    
            private void moveIt() {
                    // change the ball's state
                    int xOld = x, yOld = y;
                    x += dx;
                    y += dy;
                    bounce();
                    moved = true;                 // remember for paint's message
    
                    if ( blink ) visible = !visible;
    
                    // note: The zero-argument repaint() could replace next two lines.
                    parent.repaint(x-radius, y-radius, 2*radius, 2*radius);         
                    parent.repaint(xOld-radius, yOld-radius, 2*radius, 2*radius);
    
    //                System.out.println("thread="+Thread.currentThread());      
                    // thread=Thread[pool-1-thread-1,5,main]       <<<<<<<<< scheduled via executor
                    // thread=Thread[AWT-EventQueue-0,6,main]      //???? why 2 different type names????   startup thread
                    // thread=Thread[Thread-1,6,main]
    
                    movedCnt++;
           }  // end moveIt()
           
           int lastChecked;  // move count when last checked
    
           //  Have we moved since the last time we were called?
           public boolean checkMoved() {
             boolean moved = movedCnt > lastChecked;
             lastChecked = movedCnt;
             return moved;
           }
     
            private void bounce() {
                // note: One could argue that parent.getWidth() and getHeight()
                // are not thread-safe. That's something worth pondering.
                int parentWidth = parent.getWidth();
                if (x > parentWidth) { x = 2*parentWidth - x; dx = -dx; }
                else if (x < 0) { x = -x; dx = -dx; }      // radius vs 0   <<<<<<<<<< causes double bounce???
                int parentHeight = parent.getHeight();
                if (y < 0) { y = -y; dy = -dy; }           // saa
                else if (y > parentHeight) { y = 2*parentHeight - y; dy = -dy; }
            }
        } // end static class BallWithOwnThread
     
    }
    If you don't understand my response, don't ignore it, ask a question.

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,541
    Rep Power
    25

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    Have you tried it with just some regular class (maybe doing the coordinate maths), but no GUI?

    Also, since this is using the scheduler why are other threads being launched or sleep called?
    I'm not sure mixing the two techniques is a good idea.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  3. #3
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    The purpose of the test was to find another way to control multiple objects moving around in a GUI. The original code was using one thread per object. That solution used Thread.sleep() to get the timed motion.
    My idea was to use one thread controlled by a ScheduledThreadPoolExecutor to move the objects. Each object changes its location and then schedules another call for future moves. The problem was that some of the scheduled future moves were being lost. Sounded like a conflicting thread problem. I've tried using SwwingUtilities invokeLater and there aren't any lost tasks, but now there are longer delays on starting the future tasks.
    If you don't understand my response, don't ignore it, ask a question.

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,541
    Rep Power
    25

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    I read the original thread over at Code Ranch.

    OK, so some of the above code isn't needed?
    It's a bit confusing with the stuff in there for the (presumably) thread-based version.
    That's why I suggested paring it down, also by removing the GUI side of things.

    It should be possible to produce a small version, with no GUI, using the ScheduledThreadPoolExecutor to cycle-schedule these things.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  5. #5
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    a small version, with no GUI,
    But the GUI is the reason for the program. I think the interaction with the EDT and the painting could be causing the loss of tasks and delays.

    I left in the original code so I could easily swap between testing with one thread per ball to all balls on one thread.
    Yes it is a mess. The current version is even messier as I try different combinations of classes and methods.

    So far, using SwingUtilities invokeLater to schedule the next task doesn't lose tasks, but it does cost in delayed response times with 1000 balls.
    Using a single call to repaint without the region in each ball seems to lower the number of delayed responses.
    Moving a single repaint to its own thread (none in the ball) with a Thread sleep loop causes the losses to go up. ???
    If you don't understand my response, don't ignore it, ask a question.

  6. #6
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,541
    Rep Power
    25

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    It may be the reason for the program, but pulling out the executor does not require the GUI.
    It would at least confirm there's nothing else snarling things up.

    Similarly the other code is a mess, which would be something else to sort out because, looking at that lot as it stands, i can't tell what is likely to be executed and what isn't, hence my point about Thread.sleep() looking out of place.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  7. #7
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    Ok, here's a simpler version that loses tasks:
    Java Code:
    /* https://coderanch.com/t/682689/java/Animated-Multi-Thread-Graphical-Object
    
    Note: Added executor ->>> Problem: loses tasks???
    */
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.*; //Graphics2D;
    import java.util.ArrayList;
    import java.util.*; //List;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import java.util.concurrent.*;
    
     
    @SuppressWarnings("serial")
    
    public class ExecutorTest {
    
        ScheduledThreadPoolExecutor executor =  new ScheduledThreadPoolExecutor(4);
        ScheduledThreadPoolExecutor executor2 =  new ScheduledThreadPoolExecutor(4);
    
        java.util.List<TheTask> tasks = new ArrayList<>();
    
    
        int nbrTasks = 100;  // lose tasks with 1000 / 5-8 stopped with 100  / over 30 stopped with 500 / 20 stopped with 300 / < 10 with 200
    
     
        public static void main(String[] argv) {
    //       System.out.println("main thread="+Thread.currentThread());    // main thread=Thread[main,5,main]     
           SwingUtilities.invokeLater( () -> new ExecutorTest().startup() );
    
           //  Let test run some and then exit
           try{Thread.sleep(25000);} catch(Exception x) {}
           System.out.println(">>> main exiting <<<");
           System.exit(0);
        }
     
        public void startup() {
    //        System.out.println("startup thread="+Thread.currentThread()); // startup thread=Thread[AWT-EventQueue-0,6,main]
             Random ran = new Random();
             long start = 0L;
             TheTask bwot = null;
    
             for(int i=0; i < nbrTasks; i++) {
                int speed = 100 + ran.nextInt(300);
                tasks.add(bwot = new TheTask(speed) );
                executor.schedule((Callable<String>)bwot, start++, TimeUnit.MILLISECONDS);
             }
             
             System.out.println("starting Q size="+ executor.getQueue().size());   // starting Q size=4000
    
             //  Some balls are not moving >>> Try to find them???
             Thread t = new Thread(new Runnable() {
                   public void run() {
                      while(true) {
                         try{Thread.sleep(3000);}catch(Exception x){}
                         int cnt = 0;
                         for(TheTask bwot : tasks) {
                            if(!bwot.checkMoved())  {
                               cnt++;
                            }
                         }
                         System.out.println("Q size="+ executor.getQueue().size() +", stopped tasks = "+cnt);
                      }
                   }
             });
             t.start();
             
        }   // end startup()
    
        // See if synchronized is the cause of losing tasks >>>> No change, still loses tasks
        synchronized void doSchedule(Callable<String> ball, long time) {
            ScheduledFuture<String> sf = executor.schedule(ball, time, TimeUnit.MILLISECONDS);
        }
    
    
        //---------------------------------------------------------------
        //  Fields for saving delay times
        static int[] delays = new int[101];  // hold 0-99 and >= 100
        static int cntr = 0;
    
    
        static int id = 0;     // to create unique ids
        /*  ====================================================================================
        */
        public  class TheTask implements Callable<String> {
            private int milliseconds;
    
            public volatile int calledCnt = 0;   // to detect if any balls are not moved
            private int lastChecked;  // move count when last checked
    
            int taskId = id++;  // create new id for this task
     
            public TheTask(int milliseconds) {
                this.milliseconds = milliseconds;
            }
     
            //---------------------------------------------------------
            long lastCall = 0L;     // to compute delays
    
            @Override
            public String call() {
               long currTime = System.currentTimeMillis();
               if(lastCall != 0) {
                  int delay = (int)(currTime - lastCall); 
                  delay -= milliseconds;
                  if(delay < delays.length) delays[delay]++;
                  else delays[delays.length-1]++;
                  if(delay >  2) {                    // only show some
    //                  System.out.println(">>>>>>delayed "+ delay + " vs " + milliseconds);
                      if(cntr++ % 100 == 0)  {   // only show some
                          System.out.println("cntr="+cntr + " " +java.util.Arrays.toString(delays));
                      }
                  }
               }
               lastCall = currTime;      // save for delay comps
    
               calledCnt++;           // count for the checking that follows
                                       
               //- - - - - - - - - - -
               // schedule next move   >> many attempts are commented out to show what has been tried
    
    //           doSchedule(this, milliseconds);          // see if synch keeps from losing balls from queue??? DID NOT Help
    //           executor.schedule((Callable<String>)this, milliseconds, TimeUnit.MILLISECONDS);   //<<<<<< loses tasks
    //*
    //          javax.swing.SwingUtilities.invokeLater(        //<<  Increases delayed counts+++   lost tasks
    //           Thread t = new Thread(           //  CPU at 100% !!!!   has missing tasks!!!  >>> Too many threads created!!!!
               executor2.execute(               //  Loses tasks???  
                new Runnable() {    
                  public void run() {
                     executor.schedule((Callable<String>)TheTask.this, milliseconds, TimeUnit.MILLISECONDS);
                  }
               });
    //           t.start();
    //*/
    //           System.out.println("thread="+Thread.currentThread());      // thread=Thread[pool-1-thread-1,5,main]
               return "";           //????
           }   // end call()
              
    
           
           //  Have we been called since the last time we checked?
           public boolean checkMoved() {
             boolean moved = calledCnt > lastChecked;
             if(!moved) System.out.println(">>stopped id="+taskId + " calledCnt="+calledCnt + ", lastChecked="+lastChecked);
             lastChecked = calledCnt;        // Save current count
             return moved;
           }
     
        } // end static class TheTask
     
    }/*
    Running: java.exe -client ExecutorTest
    
    starting Q size=99
    cntr=1 [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
    Q size=96, stopped tasks = 0
    cntr=1001 [121, 258, 188, 154, 191, 155, 100, 130, 122, 101, 156, 211, 198, 173, 228, 162, 25, 2, 0, 1, 0, 0, 1, 1, 0, ...
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=96, stopped tasks = 4
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=96, stopped tasks = 4
    cntr=2001 [218, 504, 354, 281, 408, 295, 183, 250, 238, 168, 245, 400, 391, 345, 464, 345, 52, 2, 0, 1, 0, 0, 1, 1, 0, ...
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=95, stopped tasks = 4
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=47 calledCnt=62, lastChecked=62
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=95, stopped tasks = 5
    cntr=3001 [307, 753, 528, 406, 636, 442, 267, 372, 360, 236, 340, 591, 592, 518, 702, 521, 73, 2, 0, 1, 0, 0, 1, 1, 0, ...
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=47 calledCnt=62, lastChecked=62
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=95, stopped tasks = 5
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=47 calledCnt=62, lastChecked=62
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=93, stopped tasks = 5
    cntr=4001 [398, 1014, 704, 540, 863, 597, 353, 501, 482, 308, 439, 786, 803, 696, 942, 673, 93, 2, 1, 3, 0, 1, 1, 1, 0, ...
    >>stopped id=3 calledCnt=133, lastChecked=133
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=47 calledCnt=62, lastChecked=62
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=70 calledCnt=133, lastChecked=133
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=92, stopped tasks = 7
    >>> main exiting <<<
    
    0 error(s)
    */
    If you don't understand my response, don't ignore it, ask a question.

  8. #8
    benji2505 is offline Senior Member
    Join Date
    Sep 2014
    Location
    MA, USA
    Posts
    387
    Rep Power
    4

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    I am not able to recreate the problem with these sample sizes:
    starting Q size=2999
    cntr=4001 [6, 6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    Q size=3000, stopped tasks = 0
    Q size=3000, stopped tasks = 0
    Q size=3000, stopped tasks = 0
    Q size=3000, stopped tasks = 0
    Q size=3000, stopped tasks = 0
    Q size=2998, stopped tasks = 0
    Q size=3000, stopped tasks = 0
    Q size=3000, stopped tasks = 0
    >>> main exiting <<<

    I start getting problem with sample sizes of more than 3000. 'hope that info helps.

    starting Q size=4000
    >>stopped id=3006 calledCnt=0, lastChecked=0

    ....
    Q size=3999, stopped tasks = 0
    Q size=4000, stopped tasks = 0
    Q size=4000, stopped tasks = 0
    cntr=4101 [267035, 12303, 84, 55, 18, 26, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=4201 [267047, 12323, 105, 81, 68, 50, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    Q size=4000, stopped tasks = 0
    Q size=4000, stopped tasks = 0
    cntr=4301 [334169, 15418, 270, 146, 103, 54, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=4401 [334861, 15610, 418, 221, 108, 72, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=4501 [335044, 15656, 438, 250, 137, 91, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=4601 [335207, 15686, 458, 269, 165, 113, 35, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=4701 [336782, 15787, 501, 319, 208, 115, 35, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    Q size=4000, stopped tasks = 0
    >>> main exiting <<<


    My fist reaction was to manipulate the max number of threads in the Pool, but that's only doable in the parent class.
    Last edited by benji2505; 08-03-2017 at 02:51 AM.

  9. #9
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    Thanks for the response. What PC are you running on? I'm on an older HP laptop with 2.5GHz and 4MB ram, Win10 Pro
    My JRE is 8.0_144

    I've had one test run that did not have any stopped tasks. Most do.
    Your delay times are also much lower than mine. max of 8ms (most at 0 and 1) vs 15ms evenly spread

    Also your Q size is constant at 4000. Mine is always less than the number of started tasks.

    I added a Thread sleep of 1ms to the call() method after calledCnt++ and now no lost tasks:
    // With sleep(1) in call() method & 4 executors >>> NO lost tasks?? lots of delays
    Q size=996, stopped tasks = 0 CTC=82283 TC=83283
    cntr=81001 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13,
    27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 274, 567, 1193, 1892, 2521, 3224, 4688, 5588, 6833, 7520, 7883, 7455, 6900,
    5433, 4223, 3484, 2809, 1926, 1386, 940, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=82001 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13,
    27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 277, 573, 1202, 1907, 2536, 3249, 4723, 5636, 6919, 7640, 8087, 7599, 7003,
    5522, 4292, 3507, 2814, 1926, 1386, 940, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=83001 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13,
    27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 277, 589, 1267, 2007, 2695, 3410, 4865, 5745, 6991, 7704, 8167, 7629, 7005,
    5522, 4292, 3507, 2814, 1926, 1386, 940, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=84002 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13,
    27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 282, 608, 1356, 2177, 2836, 3496, 4929, 5787, 7011, 7713, 8207, 7666, 7044,
    5574, 4338, 3561, 2865, 1938, 1409, 942, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=84144 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13,
    27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 282, 608, 1356, 2177, 2841, 3512, 4954, 5815, 7050, 7740, 8209, 7666, 7044,
    5574, 4338, 3561, 2865, 1938, 1409, 942, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    >>> main exiting <<<
    Last edited by Norm; 08-03-2017 at 01:19 PM.
    If you don't understand my response, don't ignore it, ask a question.

  10. #10
    benji2505 is offline Senior Member
    Join Date
    Sep 2014
    Location
    MA, USA
    Posts
    387
    Rep Power
    4

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    I realized that the number of the core pool size does not influence the performance.

    I am running an 3.1 GHz Intel Core i7, with 16 GB 1867 MHz DDR3. JRE is 8.0_144 as well, the laptop runs on whatever is the latest OS X.

    The code ran on Eclipse though, I think they are using a separate JRE. My Eclipse version of the JRE is 8.0_121, but that should not make any difference.
    Last edited by benji2505; 08-03-2017 at 02:36 PM.

  11. #11
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    Any theories on why Benji2505 has no lost/stopped tasks and I do?

    Then what about this:
    I added a Thread sleep of 1ms to the call() method after calledCnt++ and now there are no lost tasks.
    If you don't understand my response, don't ignore it, ask a question.

  12. #12
    benji2505 is offline Senior Member
    Join Date
    Sep 2014
    Location
    MA, USA
    Posts
    387
    Rep Power
    4

    Default Re: ScheduledThreadPoolExecutor is losing tasks


  13. #13
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    When the call() method executes without the sleep, tasks are lost. Slowing it with sleep removes losing of tasks.
    On your faster machine (and different OS) no tasks are lost.

    ???


    How many thread pools did you use? I'm using 4.
    If you don't understand my response, don't ignore it, ask a question.

  14. #14
    benji2505 is offline Senior Member
    Join Date
    Sep 2014
    Location
    MA, USA
    Posts
    387
    Rep Power
    4

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    I ran examples from 1 to 10 and no change in results.

    I would check for TimeOutExceptions as described in the link. I am guessing that there are TimeOutExceptions that are not communicated.

  15. #15
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    Ok, Progress.
    I added code from the link you gave and get this:
    WestCoastScheduledExecutor created
    starting Q size=994
    cntr=1 [0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=1002 [10, 63, 70, 82, 90, 85, 90, 85, 89, 59, 75, 70, 58, 67, 67, 30, 15, 15, 4, 2, 9, 6, 2, 2, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    error in executing: ExecutorTest$TheTask@9d661f. It will no longer be run!
    error in executing: ExecutorTest$TheTask@73024. It will no longer be run!
    error in executing: ExecutorTest$TheTask@16c38b3. It will no longer be run!
    error in executing: ExecutorTest$TheTask@a62166. It will no longer be run!
    java.lang.ArrayIndexOutOfBoundsException: -1
    at ExecutorTest$TheTask.run(ExecutorTest.java:180)
    at ExecutorTest$WestCoastScheduledExecutor$LogOnExcep tionRunnable.run(ExecutorTest.java:59)
    at java.util.concurrent.Executors$RunnableAdapter.cal l(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$S cheduledFutureTask.access$201(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$S cheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker( Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    java.lang.ArrayIndexOutOfBoundsException: -1
    at ExecutorTest$TheTask.run(ExecutorTest.java:180)
    at ExecutorTest$WestCoastScheduledExecutor$LogOnExcep tionRunnable.run(ExecutorTest.java:59)
    at java.util.concurrent.Executors$RunnableAdapter.cal l(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$S cheduledFutureTask.access$201(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$S cheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker( Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    Bug in code at line 180!!!!
    Last edited by Norm; 08-03-2017 at 08:07 PM.
    If you don't understand my response, don't ignore it, ask a question.

  16. #16
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    The new code that hasn't lost any tasks in any tests I've done:
    Java Code:
    /* https://coderanch.com/t/682689/java/Animated-Multi-Thread-Graphical-Object
    
    Note: Added executor ->>> Problem: loses tasks???       Uses very little CPU < 2%
    cntr increments meaning significant delays change from time to time????
    */
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.*; //Graphics2D;
    import java.util.ArrayList;
    import java.util.*; //List;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import java.util.concurrent.*;
    
     
    @SuppressWarnings("serial")
    
    public class ExecutorTest {
      // http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/
      public class WestCoastScheduledExecutor extends ScheduledThreadPoolExecutor {
    
            public WestCoastScheduledExecutor(int corePoolSize) {
                    super(corePoolSize);
                    System.out.println("WestCoastScheduledExecutor created"); //<<<<<<<<show we're used
            }
    
            @Override
            public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
                    return super.scheduleAtFixedRate(wrapRunnable(command), initialDelay, period, unit);
            }
    
            @Override
            public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
                    return super.scheduleWithFixedDelay(wrapRunnable(command), initialDelay, delay, unit);
            }
    
            @Override 
            public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {    // Added
                  return super.schedule(wrapRunnable(command), delay, unit);                  //<<<<
            }
    
            private Runnable wrapRunnable(Runnable command) {
                    return new LogOnExceptionRunnable(command);
            }
    
            private class LogOnExceptionRunnable implements Runnable {
                 private Runnable theRunnable;
    
                 public LogOnExceptionRunnable(Runnable theRunnable) {
                      super();
                      this.theRunnable = theRunnable;
                 }
    
                 @Override
                 public void run() {
                      try {
                           theRunnable.run();
                      } catch (Exception e) {
                           // LOG IT HERE!!!
                           System.err.println("error in executing: " + theRunnable + ". It will no longer be run!");
                           e.printStackTrace();
    
                           // and re throw it so that the Executor also gets this error so that it can do what it would
                           // usually do
                           throw new RuntimeException(e);
                      }
                 }
            }
        }  // end WestCoastScheduledExecutor  class
    
        ScheduledThreadPoolExecutor executor =  new WestCoastScheduledExecutor(4); //ScheduledThreadPoolExecutor(4);
        //  many delays > 100ms with pool=2 & 3 >> 280 >100ms with 4
    
        ScheduledThreadPoolExecutor executor2 =  new ScheduledThreadPoolExecutor(4);
    
        java.util.List<TheTask> tasks = new ArrayList<>();
    
        static class Counter {
           public int cnt = 1; // start at 1
           public String toString() {
              return "count="+cnt;
           }
        }
    
        static Map<String, Counter> countThrds = new HashMap<>();
    
        //===========================================
        int nbrTasks = 1000;  // w/o sleep:  lose tasks with 1000 / 5-8 stopped with 100  / over 30 stopped with 500 / 20 stopped with 300 / < 10 with 200
        int showCntrAt = 1000;  // how often to show nctr values
        //===========================================
    
     
        public static void main(String[] argv) {
    //       System.out.println("main thread="+Thread.currentThread());    // main thread=Thread[main,5,main]     
           SwingUtilities.invokeLater( () -> new ExecutorTest().startup() );
    
           //  Let test run some and then exit
           try{Thread.sleep(25000);} catch(Exception x) {}
           System.out.println("cntr="+cntr + " " +java.util.Arrays.toString(delays));
           System.out.println("map="+countThrds);
           // map={pool-1-thread-1=count=22779, pool-1-thread-3=count=22795, pool-1-thread-2=count=22774, pool-1-thread-4=count=22754}
    
    
           System.out.println(">>> main exiting <<<");
           System.exit(0);
        }
     
        public void startup() {
    //        System.out.println("startup thread="+Thread.currentThread()); // startup thread=Thread[AWT-EventQueue-0,6,main]
             Random ran = new Random();
             long start = 0L;
             TheTask bwot = null;
    
             for(int i=0; i < nbrTasks; i++) {
                int speed = 100 + ran.nextInt(300);
                tasks.add(bwot = new TheTask(speed) );
                executor.schedule(/*(Callable<String>)*/bwot, start++, TimeUnit.MILLISECONDS);
             }
             
             System.out.println("starting Q size="+ executor.getQueue().size());   // starting Q size=4000
    
             //  Some balls are not moving >>> Try to find them???
             Thread t = new Thread(new Runnable() {
                   public void run() {
                      while(true) {
                         try{Thread.sleep(3000);}catch(Exception x){}
                         int cnt = 0;
                         for(TheTask bwot : tasks) {
                            if(!bwot.checkMoved())  {
                               cnt++;
                            }
                         }
                         System.out.println("Q size="+ executor.getQueue().size() +", stopped tasks = "+cnt
                                           + "   CTC="+executor.getCompletedTaskCount() + "  TC="+executor.getTaskCount());
                      }
                   }
             });
             t.start();
             
        }   // end startup()
    
        // See if synchronized is the cause of losing tasks >>>> No change, still loses tasks
        synchronized void doSchedule(Callable<String> ball, long time) {
            ScheduledFuture<String> sf = executor.schedule(ball, time, TimeUnit.MILLISECONDS);
        }
    
    
        //---------------------------------------------------------------
        //  Fields for saving delay times
        static int[] delays = new int[101];  // hold 0-99 and >= 100
        static int cntr = 0;
    
    
        static int id = 0;     // to create unique ids
        /*  ====================================================================================
        */
        public  class TheTask implements Runnable { //Callable<String> {
            private int milliseconds;
    
            public volatile int calledCnt = 0;   // to detect if any balls are not moved
            private int lastChecked;  // move count when last checked
    
            int taskId = id++;  // create new id for this task
     
            public TheTask(int milliseconds) {
                this.milliseconds = milliseconds;
            }
     
            //---------------------------------------------------------
            long lastCall = 0L;     // to compute delays
    
            @Override
            public void run() { // String call() {
               long currTime = System.currentTimeMillis();
               if(lastCall != 0) {
                  int delay = (int)(currTime - lastCall); 
    //              if(currTime-lastCall < milliseconds)  System.out.println(">>> currTime="+currTime + ", lastCall="+lastCall +", delay ="+delay + " ms="+milliseconds);
                  // >>> currTime=1501784344459, lastCall=1501784344100, delay =359 ms=360   ??? delay < ms ???
                  // >>> currTime=1501784344459, lastCall=1501784344084, delay =375 ms=376
                  delay -= milliseconds;
                  if(delay < 0) {
    //                 System.out.println(">>> currTime="+currTime + ", lastCall="+lastCall +", delay ="+delay);
                     delay = 0;
                  }
                  if(delay < delays.length) delays[delay]++;      //<<<<<<<<<<<<< -1
                  else delays[delays.length-1]++;
                  if(delay >  2) {                    // only show some
    //                  System.out.println(">>>>>>delayed "+ delay + " vs " + milliseconds);
                      if(cntr++ % showCntrAt == 0)  {   // only show some
                          System.out.println("cntr="+cntr + " " +java.util.Arrays.toString(delays));
                      }
                  }
               }
               lastCall = currTime;      // save for delay comps
    
               calledCnt++;           // count for the checking that follows
               
               // count number of times this thread used
               String tName = Thread.currentThread().getName();
               Counter cntr = countThrds.get(tName);
               if(cntr == null)
                  countThrds.put(tName, new Counter());
               else
                  cntr.cnt++;
    
    
    //           try{Thread.sleep(1);} catch(Exception x) {}     // Do some work    NO Missing tasks ??? But > 100ms delays ???? w/1 executor   CPU 8%
    
                                       
               //- - - - - - - - - - -
               // schedule next move   >> many attempts are commented out to show what has been tried
    
    //           doSchedule(this, milliseconds);          // see if synch keeps from losing balls from queue??? DID NOT Help
    //           executor.schedule((Callable<String>)this, milliseconds, TimeUnit.MILLISECONDS);   //<<<<<< loses tasks
    //*
              javax.swing.SwingUtilities.invokeLater(        //<<  Increases delayed counts+++   lost tasks
    //           Thread t = new Thread(           //  CPU at 100% !!!!   has missing tasks!!!  >>> Too many threads created!!!!
    //           executor2.execute(               //  Loses tasks???  
                new Runnable() {    
                  public void run() {
                     executor.schedule(/*(Callable<String>)*/TheTask.this, milliseconds, TimeUnit.MILLISECONDS);
                  }
               });
    //           t.start();
    //*/
    //           System.out.println("thread="+Thread.currentThread());      // thread=Thread[pool-1-thread-1,5,main]
    //           return "";           //????
           }   // end call()
              
    
           
           //  Have we been called since the last time we checked?
           public boolean checkMoved() {
             boolean moved = calledCnt > lastChecked;
    //         if(!moved) System.out.println(">>stopped id="+taskId + " calledCnt="+calledCnt + ", lastChecked="+lastChecked);
             lastChecked = calledCnt;        // Save current count
             return moved;
           }
     
        } // end static class TheTask
     
    }/*
    Running: java.exe -client ExecutorTest
    
    starting Q size=99
    cntr=1 [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
    Q size=96, stopped tasks = 0
    cntr=1001 [121, 258, 188, 154, 191, 155, 100, 130, 122, 101, 156, 211, 198, 173, 228, 162, 25, 2, 0, 1, 0, 0, 1, 1, 0, ...
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=96, stopped tasks = 4
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=96, stopped tasks = 4
    cntr=2001 [218, 504, 354, 281, 408, 295, 183, 250, 238, 168, 245, 400, 391, 345, 464, 345, 52, 2, 0, 1, 0, 0, 1, 1, 0, ...
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=95, stopped tasks = 4
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=47 calledCnt=62, lastChecked=62
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=95, stopped tasks = 5
    cntr=3001 [307, 753, 528, 406, 636, 442, 267, 372, 360, 236, 340, 591, 592, 518, 702, 521, 73, 2, 0, 1, 0, 0, 1, 1, 0, ...
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=47 calledCnt=62, lastChecked=62
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=95, stopped tasks = 5
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=47 calledCnt=62, lastChecked=62
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=93, stopped tasks = 5
    cntr=4001 [398, 1014, 704, 540, 863, 597, 353, 501, 482, 308, 439, 786, 803, 696, 942, 673, 93, 2, 1, 3, 0, 1, 1, 1, 0, ...
    >>stopped id=3 calledCnt=133, lastChecked=133
    >>stopped id=30 calledCnt=8, lastChecked=8
    >>stopped id=47 calledCnt=62, lastChecked=62
    >>stopped id=53 calledCnt=9, lastChecked=9
    >>stopped id=70 calledCnt=133, lastChecked=133
    >>stopped id=78 calledCnt=27, lastChecked=27
    >>stopped id=85 calledCnt=17, lastChecked=17
    Q size=92, stopped tasks = 7
    >>> main exiting <<<
    
    0 error(s)
    
    Running: java.exe -client ExecutorTest
    
    starting Q size=100
    cntr=1 [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    Q size=96, stopped tasks = 0 CTC=1256  TC=1352          <<< note: CTC+size=TC
    cntr=1001 [11, 75, 66, 55, 73, 101, 100, 76, 56, 117, 89, 53, 91, 89, 64, 41, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    >>stopped id=3 calledCnt=2, lastChecked=2
    >>stopped id=4 calledCnt=2, lastChecked=2
    cntr=2002 [23, 152, 140, 113, 150, 204, 210, 158, 117, 221, 171, 104, 176, 184, 122, 77, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    >>stopped id=22 calledCnt=1, lastChecked=1
    >>stopped id=68 calledCnt=2, lastChecked=2
    Q size=92, stopped tasks = 4 CTC=2436  TC=2528
    >>stopped id=3 calledCnt=2, lastChecked=2
    >>stopped id=4 calledCnt=2, lastChecked=2
    >>stopped id=6 calledCnt=22, lastChecked=22
    >>stopped id=7 calledCnt=20, lastChecked=20
    >>stopped id=22 calledCnt=1, lastChecked=1
    >>stopped id=56 calledCnt=18, lastChecked=18
    >>stopped id=58 calledCnt=12, lastChecked=12
    >>stopped id=68 calledCnt=2, lastChecked=2
    Q size=92, stopped tasks = 8 CTC=3588  TC=3680
    cntr=3001 [35, 229, 211, 172, 225, 309, 321, 240, 178, 323, 255, 154, 258, 275, 182, 114, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    >>stopped id=3 calledCnt=2, lastChecked=2
    >>stopped id=4 calledCnt=2, lastChecked=2
    >>stopped id=6 calledCnt=22, lastChecked=22
    >>stopped id=7 calledCnt=20, lastChecked=20
    >>stopped id=22 calledCnt=1, lastChecked=1
    >>stopped id=56 calledCnt=18, lastChecked=18
    >>stopped id=58 calledCnt=12, lastChecked=12
    >>stopped id=68 calledCnt=2, lastChecked=2
    Q size=92, stopped tasks = 8 CTC=4752  TC=4844
    cntr=4001 [47, 307, 284, 230, 301, 413, 430, 321, 240, 421, 343, 206, 338, 372, 240, 150, 9, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    >>stopped id=3 calledCnt=2, lastChecked=2
    >>stopped id=4 calledCnt=2, lastChecked=2
    >>stopped id=6 calledCnt=22, lastChecked=22
    >>stopped id=7 calledCnt=20, lastChecked=20
    >>stopped id=22 calledCnt=1, lastChecked=1
    >>stopped id=56 calledCnt=18, lastChecked=18
    >>stopped id=58 calledCnt=12, lastChecked=12
    >>stopped id=68 calledCnt=2, lastChecked=2
    Q size=92, stopped tasks = 8 CTC=5910  TC=6002
    cntr=5001 [59, 385, 355, 289, 378, 519, 538, 402, 299, 525, 427, 259, 419, 465, 298, 182, 14, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    >>stopped id=3 calledCnt=2, lastChecked=2
    >>stopped id=4 calledCnt=2, lastChecked=2
    >>stopped id=6 calledCnt=22, lastChecked=22
    >>stopped id=7 calledCnt=20, lastChecked=20
    >>stopped id=22 calledCnt=1, lastChecked=1
    >>stopped id=56 calledCnt=18, lastChecked=18
    >>stopped id=58 calledCnt=12, lastChecked=12
    >>stopped id=68 calledCnt=2, lastChecked=2
    Q size=88, stopped tasks = 8 CTC=7029  TC=7117
    cntr=6001 [72, 466, 425, 349, 458, 625, 645, 486, 361, 626, 494, 299, 506, 560, 361, 221, 16, 1, 3, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    >>stopped id=3 calledCnt=2, lastChecked=2
    >>stopped id=4 calledCnt=2, lastChecked=2
    >>stopped id=6 calledCnt=22, lastChecked=22
    >>stopped id=7 calledCnt=20, lastChecked=20
    >>stopped id=22 calledCnt=1, lastChecked=1
    >>stopped id=37 calledCnt=71, lastChecked=71
    >>stopped id=56 calledCnt=18, lastChecked=18
    >>stopped id=58 calledCnt=12, lastChecked=12
    >>stopped id=68 calledCnt=2, lastChecked=2
    >>stopped id=95 calledCnt=66, lastChecked=66
    >>stopped id=97 calledCnt=55, lastChecked=55
    >>stopped id=98 calledCnt=55, lastChecked=55
    Q size=84, stopped tasks = 12 CTC=8132  TC=8216
    cntr=7001 [84, 550, 499, 412, 541, 735, 755, 568, 426, 733, 556, 339, 592, 657, 416, 258, 18, 1, 4, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    >>stopped id=3 calledCnt=2, lastChecked=2
    >>stopped id=4 calledCnt=2, lastChecked=2
    >>stopped id=6 calledCnt=22, lastChecked=22
    >>stopped id=7 calledCnt=20, lastChecked=20
    >>stopped id=8 calledCnt=163, lastChecked=163
    >>stopped id=22 calledCnt=1, lastChecked=1
    >>stopped id=37 calledCnt=71, lastChecked=71
    >>stopped id=44 calledCnt=62, lastChecked=62
    >>stopped id=56 calledCnt=18, lastChecked=18
    >>stopped id=58 calledCnt=12, lastChecked=12
    >>stopped id=68 calledCnt=2, lastChecked=2
    >>stopped id=76 calledCnt=130, lastChecked=130
    >>stopped id=77 calledCnt=50, lastChecked=50
    >>stopped id=95 calledCnt=66, lastChecked=66
    >>stopped id=97 calledCnt=55, lastChecked=55
    >>stopped id=98 calledCnt=55, lastChecked=55
    Q size=83, stopped tasks = 16 CTC=9187  TC=9270
    cntr=8001 [98, 636, 580, 477, 626, 852, 867, 655, 497, 845, 603, 378, 678, 759, 459, 284, 22, 1, 5, 0, 1, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    cntr=8073 [99, 643, 586, 482, 632, 860, 880, 660, 500, 853, 607, 381, 682, 769, 460, 286, 22, 1, 5, 0, 1, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    >>> main exiting <<<
    
    0 error(s)
    //   With sleep(1) in call() method & 4 executoes >>> NO lost tasks??  lots of delays
    Q size=996, stopped tasks = 0   CTC=82283  TC=83283
    cntr=81001 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13,
     27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 274, 567, 1193, 1892, 2521, 3224, 4688, 5588, 6833, 7520, 7883, 7455, 6900, 
     5433, 4223, 3484, 2809, 1926, 1386, 940, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=82001 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13,
     27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 277, 573, 1202, 1907, 2536, 3249, 4723, 5636, 6919, 7640, 8087, 7599, 7003, 
     5522, 4292, 3507, 2814, 1926, 1386, 940, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=83001 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13, 
     27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 277, 589, 1267, 2007, 2695, 3410, 4865, 5745, 6991, 7704, 8167, 7629, 7005, 
     5522, 4292, 3507, 2814, 1926, 1386, 940, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=84002 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13, 
     27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 282, 608, 1356, 2177, 2836, 3496, 4929, 5787, 7011, 7713, 8207, 7666, 7044, 
     5574, 4338, 3561, 2865, 1938, 1409, 942, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=84144 [0, 91, 360, 212, 67, 48, 24, 24, 23, 25, 10, 7, 16, 9, 10, 9, 6, 13, 6, 3, 36, 24, 44, 30, 31, 6, 21, 6, 10, 15, 16, 30, 21, 26, 13, 
     27, 9, 11, 19, 40, 42, 26, 9, 2, 11, 7, 12, 17, 6, 22, 46, 67, 153, 282, 608, 1356, 2177, 2841, 3512, 4954, 5815, 7050, 7740, 8209, 7666, 7044, 
     5574, 4338, 3561, 2865, 1938, 1409, 942, 709, 566, 437, 333, 210, 90, 61, 49, 58, 131, 136, 66, 39, 28, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    >>> main exiting <<<
    
    0 error(s)
                  // Again with sleep(1) & 4 ex
    Q size=996, stopped tasks = 0   CTC=82410  TC=83410
    ..
    cntr=84442 [0, 40, 198, 125, 89, 62, 76, 43, 34, 10, 13, 14, 25, 6, 21, 25, 14, 4, 2, 1, 9, 10, 9, 9, 7, 7, 6, 5, 9, 14, 20, 21, 20, 7, 5, 6, 5, 
      7, 8, 3, 16, 36, 27, 6, 8, 34, 58, 51, 70, 155, 262, 428, 825, 1573, 2558, 3412, 4539, 5292, 6085, 6896, 6992, 6831, 6225, 5453, 4877, 4011, 
      2940, 2245, 1610, 1462, 1137, 925, 895, 797, 627, 414, 217, 125, 152, 175, 197, 297, 337, 191, 243, 261, 231, 192, 275, 211, 157, 155, 168, 151, 
      112, 68, 24, 14, 2, 2, 0]
    map={pool-1-thread-1=count=21448, pool-1-thread-3=count=21444, pool-1-thread-2=count=21467, pool-1-thread-4=count=21447}
    >>> main exiting <<<
    
    0 error(s)
    
    
    Running: java.exe -client ExecutorTest
    
    WestCoastScheduledExecutor created
    starting Q size=994
    cntr=1 [0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=1002 [10, 63, 70, 82, 90, 85, 90, 85, 89, 59, 75, 70, 58, 67, 67, 30, 15, 15, 4, 2, 9, 6, 2, 2, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    error in executing: ExecutorTest$TheTask@9d661f. It will no longer be run!
    error in executing: ExecutorTest$TheTask@73024. It will no longer be run!
    error in executing: ExecutorTest$TheTask@16c38b3. It will no longer be run!
    error in executing: ExecutorTest$TheTask@a62166. It will no longer be run!
    java.lang.ArrayIndexOutOfBoundsException: -1
    	at ExecutorTest$TheTask.run(ExecutorTest.java:180)                  //<<<<<<<<<< BUG HERE!!!!  <<<<<<<<<<<<<<<<<
    	at ExecutorTest$WestCoastScheduledExecutor$LogOnExceptionRunnable.run(ExecutorTest.java:59)
    	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    	at java.util.concurrent.FutureTask.run(Unknown Source)
    	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
    	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    	at java.lang.Thread.run(Unknown Source)
    
    //-----------------------------------------------
       //  with bug fixed and w/o sleep(1)   4 threads
    cntr=90001 [5245, 4979, 6326, 6238, 6755, 7699, 7858, 7536, 7681, 6592, 7357, 5978, 7130, 4898, 5967, 4747, 2678, 717, 96, 39, 14, 10, 25, 
      7, 13, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    cntr=90906 [5291, 5027, 6397, 6299, 6820, 7782, 7939, 7616, 7759, 6659, 7430, 6036, 7208, 4950, 6030, 4796, 2707, 718, 96, 39, 14, 10, 25, 
      7, 13, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    map={pool-1-thread-1=count=27399, pool-1-thread-3=count=27201, pool-1-thread-2=count=27063, pool-1-thread-4=count=27178}    ??? 27*4 = 108 vs 91
    >>> main exiting <<<
    cntr=91001 [5295, 5031, 6403, 6303, 6830, 7789, 7945, 7626, 7766, 6670, 7436, 6041, 7214, 4954, 6034, 4798, 2707, 718, 96, 39, 14, 10, 25,
      7, 13, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    
    0 error(s)
    
    
    */
    If you don't understand my response, don't ignore it, ask a question.

  17. #17
    benji2505 is offline Senior Member
    Join Date
    Sep 2014
    Location
    MA, USA
    Posts
    387
    Rep Power
    4

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    line 180 is where is surfaces. Looks to me like a concurrency problem within ScheduledThreadPoolExecutor. Why else would an ArrayIndexOutOfBoundsException be dependent on OS or computing power?

  18. #18
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,942
    Rep Power
    30

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    Looks to me like a concurrency problem within ScheduledThreadPoolExecutor.
    The actual cause was a programming problem. I had assumed that the time of dispatch for the task would be at the requested time or later. It seems that it can be before hence a negative index for the delay. The code at line 183 fixed that,

    Now a question might be: how can the start time be before the requested time? How is that related to CPU power or a sleep(1)?
    If you don't understand my response, don't ignore it, ask a question.

  19. #19
    benji2505 is offline Senior Member
    Join Date
    Sep 2014
    Location
    MA, USA
    Posts
    387
    Rep Power
    4

    Default Re: ScheduledThreadPoolExecutor is losing tasks

    Quote Originally Posted by Norm View Post
    Now a question might be: how can the start time be before the requested time? How is that related to CPU power or a sleep(1)?
    And why is it dependent on a local Integer variable below or above a threshold value of 1000 or 3000 or whatever.

Similar Threads

  1. losing motivation and need help
    By nicocannon in forum Forum Lobby
    Replies: 7
    Last Post: 01-18-2017, 12:50 PM
  2. Losing sleep over this
    By MW130 in forum New To Java
    Replies: 6
    Last Post: 02-02-2014, 06:44 PM
  3. Losing data from array - not sure why
    By neveser in forum New To Java
    Replies: 8
    Last Post: 12-02-2012, 07:19 AM
  4. JTabbedPane losing listener
    By mendescholl in forum AWT / Swing
    Replies: 1
    Last Post: 02-03-2012, 03:01 AM
  5. Replies: 0
    Last Post: 08-01-2011, 05:11 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •