Run code every n invocations
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.