简体   繁体   中英

Disable Thread.sleep()

I want to disable possibility of using Thread.sleep() in a java project and use my own method instead:

sleep(int time, String info)

That will wait for given amount of time, and print info why is waiting necessary here.

Is disabling Thread.sleep() possible?

If yes, what's best method to do so?

The best method would be to have hook on some static code analysis tool to mark build as failed if there are any invocations of Thread.Sleep() .

You could probably configure SonarCube to do this.

Yes, sure.

Just make sure that no code in that project is calling Thread.sleep() ; but your MyUtility.sleep() replacement.

If the question is: can I somehow change the behavior of the existing Thread.sleep(), then the answer is: depends on context/effort you are willing to spend.

Well, with certain tricks; it might be possible; but simply speaking: it is a most likely a bad idea; and not worth following up on. I would really shy away from changing the code behavior, if at all I would look into those solutions that can identify usages of that unwanted sleep calls at compile time.

You can use AOP to intercept calls to Thread.sleep() and "redirect" call to your one via aroundAdvice. When original Thread.sleep() is invoked, a "default cause" is added. This one shows an example about how you can use it (remember to create a AspectJ project, or Aspects will not work):

SleepAspect.java

package org.norsam.so.sleep

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class SleepAspect
{
    @Around("call (* java.lang.Thread.sleep(..) )")
    public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable
    {
        StackTraceElement ste = Thread.currentThread().getStackTrace()[2];
        Long ms = (Long) point.getArgs()[0];
        String m = ste.getMethodName();
        String c = ste.getClassName();
        String skip = SleepClass.class.getName();
        if (c.equals(skip) && m.equals("sleep")) {
            System.out.println("sleep well for " + ms + "ms!");
        } else {
            SleepClass.sleep(ms, "Thread.sleep invoked in " + c + "." + m + ", no cause present!");
        }
        Object toret = point.proceed();
        return toret;
    }

}

SleepClass.java

package org.norsam.so.sleep

public class SleepClass {

    public static void sleep(long l, String cause) {
        System.out.println("CAUSE: " + cause);
        try {
            Thread.sleep(l);
        } catch (InterruptedException e) {
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SleepClass.sleep(1000, "I love to sleep 1000");
        Thread.sleep(2000L);
        System.out.println("Bye");
    }

}

When you run it, you receive something like

CAUSE: I love to sleep 1000
sleep well for 1000ms!
CAUSE: Thread.sleep invoked in org.norsam.so.sleep.SleepClass.main, no cause present!
sleep well for 2000ms!
Bye

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM