Run code every n invocations I came across a situation where I needed code to run every n invocations of a method.  Specifically, I was clearing out massive amounts of data and needed to hint to the VM that it should run garbage collection.  My solution was a little more condensed than this, but this class offers reuseability and ensures accurate counts.

public class ExecutionLimiter {
    private final AtomicInteger ai = new AtomicInteger(0);
    private final Runnable task;
    private final int runEvery;

    public ExecutionLimiter(Runnable task, int runEvery){
        this.task = task;
        this.runEvery = runEvery;
    }

    public boolean tryRun(){
        synchronized(ai){
            if(ai.incrementAndGet() != runEvery) return false;
            ai.set(0);
        }
        task.run();
        return true;
    }

    public static void main(String... args) throws InterruptedException{
        AtomicInteger example = new AtomicInteger(0);
        ExecutorService service = Executors.newWorkStealingPool(5);
        ExecutionLimiter limiter = new ExecutionLimiter(example::incrementAndGet, 10);

        int invocations = 100;

        for(int i=0;i&lt;invocations;i++){
            service.submit(()-&gt;{
                try{
                    Thread.sleep(Math.round(Math.random() * 1000));
                }catch(InterruptedException ignore){}
                if(limiter.tryRun())
                    System.out.println(Thread.currentThread().getName() +
                            ": Successfully ran: value is " + example.get());
            });
        }

        service.shutdown();
        service.awaitTermination(invocations, TimeUnit.SECONDS);
    }
}


I can't help but feel that something like this exists already in Java, but I haven't been able to find it.  The closest I've come is CyclicBarrier, but I don't want to hang my threads while incrementing.

A few concerns:


Is AtomicInteger overkill for this class?  Would it be better to use an int and synchronize on a lock Object?
Should I be synchronizing AtomicInteger to perform the incrementAndGet-and-set, or is there a better way to go about this?


The main is just for demonstration.
synchronized(ai){
            if(ai.incrementAndGet() != runEvery) return false;
            ai.set(0);
        }



You should either use AtomicInteger or use synchronized.  Using both together is certainly overkill.  

Consider 

    private static int count = 0;
    private static final Object lock = new Object();


and later 

        synchronized (lock) {
            if (++count != runEvery) {
                return false;
            }

            count = 0;
        }


Then you don't need the AtomicInteger at all.  

I prefer a descriptive name like count to an abbreviated type name like ai.  This is especially so in this case, as my natural expansion of AI is Artificial Intelligence.  

You use AtomicInteger when you don't want to use a synchronized block.  Perhaps 

        int current = ai.incrementAndGet();
        if (current % runEvery != 0) {
            return false;
        }

        int next = 0;
        do {
            if (ai.compareAndSet(current, next) {
                task.run();
                return true;
            }
            current = ai.get();
            next = current - runEvery;
        } while (next &gt;= 0);


Obviously this is more complicated than the synchronized version.  But this is how one uses an AtomicInteger.  

The modulus is more reliable in case of high contention that keeps compareAndSet from returning true.  

If we aren't worried that the count will overflow the bounds of integer, we can get rid of the reset.  Without the reset, this makes more sense:  

        if (ai.incrementAndGet() % runEvery != 0) {
            return false;
        }


That's how an AtomicInteger is supposed to work.  Even if two threads call this code at the same time, only one will get past the check.  Because the update happens atomically.  The problem with the original code is that there are actually two updates and you need to synchronize them.  

Of course, if the range for ai is not constrained, then it will overflow eventually.  The synchronized block is more reliable in that case.  This usage fits synchronized better than atomic types because there's no atomic increment, compare, and reset operation.  

You could also use an explicit Lock here, but you don't seem to need it.  The blocking behavior of synchronized better matches what you are doing.  The lock would be better if it were OK to only sometimes update (when you can get the lock) and sometimes not (when you can't get the lock).  But that's not what you are doing here.  

It would be possible to create a new class with the necessary method (countCompareReset), but it may be simpler just to use the lock variable with the synchronization block.