Daily Archives: August 27, 2021

Producer, Consumer with ReentrantLock, Condition

public class PC {

    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Condition added = lock.newCondition();
        Condition removed = lock.newCondition();
        int[] resource = new int[1];
        Consumer c1 = new Consumer(lock, added, removed, resource);
        Producer p1 = new Producer(lock, added, removed, resource);
        Producer p2 = new Producer(lock, added, removed, resource);
        new Thread(c1).start();
        new Thread(p1).start();
        new Thread(p2).start();
    }


    public static class Consumer implements Runnable {

        ReentrantLock lock;
        Condition added;
        Condition removed;
        int[] resource;

        public Consumer(ReentrantLock lock, Condition added, Condition removed, int[] resource) {
            this.lock = lock;
            this.resource = resource;
            this.added = added;
            this.removed = removed;
        }

        @SneakyThrows
        public void run() {
            while (true) {
                lock.lock();
                while (resource[0] <= 0) {
                    added.await();
                }
                resource[0]--;
                System.out.println(Thread.currentThread().getId() + " consume: " + resource[0]);
                removed.signalAll();
                lock.unlock();
                Thread.sleep(1000l);
            }
        }

    }

    public static class Producer implements Runnable {

        ReentrantLock lock;
        Condition added;
        Condition removed;
        int[] resource;
        int MAX = 5;

        public Producer(ReentrantLock lock, Condition added, Condition removed, int[] resource) {
            this.lock = lock;
            this.resource = resource;
            this.added = added;
            this.removed = removed;
        }

        @SneakyThrows
        public void run() {
            while (true) {
                lock.lock();
                while (resource[0] >= MAX) {
                    removed.await();
                }
                resource[0]++;
                System.out.println(Thread.currentThread().getId() + " produce: " + resource[0]);
                added.signalAll();
                lock.unlock();
                Thread.sleep(1000l);
            }
        }

    }

}

Token Bucket

public class TokenBucket {

    private long maxBucketSize;
    private long refillRate; // per second
    private long currentBucketSize;
    private long lastRefillTimestamp;

    synchronized public boolean allowRequest(int token) {
        refill();
        if (currentBucketSize >= token) {
            currentBucketSize -= token;
            return true;
        }
        return false;
    }

    private void refill() {
        long now = System.nanoTime();
        double add = (now - lastRefillTimestamp) / 1e9 * refillRate;
        currentBucketSize = Math.min(currentBucketSize + (long)add, maxBucketSize);
        lastRefillTimestamp = now;
    }

}

groupon design

rule: {
    rule_id,
    type: discount/one-time
    value: 30%/50$
    limited_user: [usr1, usr2]
    limited_user_grp: [grp1, grp2]
    number_of_usage: 1,
    service: [LYFT, CHIPOTLE]
}

groupon: {
    g_id,
    code: XMASCODE
    rule_id: xxx
    expire_date: 2021/12/31
}

usage: {
    user_id,
    groupon_id,
    time
}