Thread.sleep() is hung?

若如初见. 提交于 2019-11-30 04:45:47

In addition to what bdonlan mentioned you may want to look into ScheduledThreadPoolExecutor. I work on a very similar type of project and this object has made my life easier, thanks to this little snippet.

ScheduleAtFixedRate

If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.

I hope this helps!

Are you depending on the system tick count to increase monotonically?

From what I've heard from someone experienced, it (occasionally) happens that the system tick goes backwards by one or two ticks. I haven't experienced it myself yet, but if you're depending on this, might this explain what's happening?

Edit:

When I said System.currentTimeMillis(), I believe I was mistaken. I thought that System.currentTimeMillis() is similar to Windows' GetTickCount() function (i.e. it is measures a time that is independent of the system time), but in fact, that does not seem to be the case. So of course it can change, but that was not my point: apparently, tick counts measured by the system timer can also go backwards by a tick or two, even ignoring system time changes. Not sure if that helps, but thanks to Raedwald for pointing out the system time change possibility, since that's not what I meant.

I know that you looked in jconsole, but it might be useful to send signal 3 to the process (that is, kill -3) and post more of the resulting thread dump here. Or, if you really want to get into the details, then you might consider taking one or more pstack/jstack dumps of the hung process in quick succession in order to show where the threads really are. Information is available online about how to correlate this information with a java thread dump.

Also, by "one of our servers," are you saying that the problem is reproducible on one server, but it never occurs on other servers? This indicates a problem with that one server. Check that everything is the same across your servers and that there are no issues on that hardware in particular.

Finally, this might not be a java problem per se. Thread.sleep(long) is a native method (maps directly onto the underlying operating system's thread management), so check that your OS is up to date.

Have you considered using Timer & TimerTask.

Here is simple snippet which might help.

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class Example {

    public static void main(String args[]) {
        Timer timer = new Timer();

        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                Calendar instance = Calendar.getInstance();
                System.out.println("time: " + instance.getTime() + " : " + instance.getTimeInMillis());

                // check db for new jobs and
                // kick off thread if necessary
            }
        };

        int startingDelay = 0; // timer task will be started after startingDelay
        int period = 1000; // you are using it as sleeping time in your code
        timer.scheduleAtFixedRate(task, startingDelay, period);
    }

}

EDIT

According to the discussions I have studied, Thread.sleep() is the sign of poorly designed code. Reasons are

  • ...The thread does not lose ownership of any monitors (from documentation).
  • Blocks the thread from execution.
  • And obviously it does not give any guarantee, that execution will start after sleeping time.
  • To me, it is so much primitive to use Thread.sleep(). There is a whole package dedicated to concurrency.

Which one is better instead of Thread.sleep()? Which raises another question. I would suggest you to have a look in Concurrency chapter from the book Effective Java.

Thread.sleep() is not a good practice in Java programming. Just Google "Is Thread.sleep() bad?" and you will see my point.

Firstly, it makes the current Thread inaccessible by other parts of the program especially if it is multi-threaded. Maybe that is why you are experiencing the hang.

Secondly, it would be catastrophic if the current thread is EDT (Event Dispatch Thread) and the application has Swing GUI.

A better alternative would be Object.wait() :

final Object LOCK = new Object();
final long SLEEP = 1000;

public void run() {
  while (true) {
    // check db for new jobs and 
    // kick off thread if necessary

    try {
      synchronize (LOCK) {
        LOCK.wait(SLEEP);
      }
    } catch (InterruptedException e) {
      // usually interrupted by other threads e.g. during program shutdown
      break;
    }

  }
}

maybe you can try another tool other than Jconsole to first confirm that it is block in the sleep api.

For example, manually try using jstack to print it to file for many times and check the result.

Or use a better tool, such as Youkit (commercail) if your org has its license to profile the application in depth, or remote debug (maybe can not in production)

OR You can check whether the "// check db for new jobs " code is run during. by checking loggings, or profile, or any other method depends on your application........ If the check db is very quick, and then sleep 1 seconds, if is very likely that you always see sleep in stack trace just because the compared probability....

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!