同步java问题

问题描述 投票:0回答:1

我正在尝试实施令牌桶速率限制器。下面是我写的基本代码,但没有得到预期的结果。好像我遗漏了一些东西,或者我还没有完全理解如何在 java 中使用线程函数。有人可以帮助我寻找正确的方向吗?

public class RateLimiterTokenBucket implements RateLimiter, Runnable{

    Integer capacity;
    Integer frequencyInMilliseconds;
    Integer currentCapacity;

    public RateLimiterTokenBucket(Integer frequencyInMilliseconds,Integer capacity) {
        this.frequencyInMilliseconds = frequencyInMilliseconds;
        this.capacity = capacity;
        this.currentCapacity = capacity;
    }

    @Override
    public boolean consume() {
        synchronized (currentCapacity) {
            if(currentCapacity <= 0) return false;
            --currentCapacity;
            return true;
        }
    }

    @Override
    public void run() {
        synchronized (currentCapacity) {
            OffsetDateTime t = OffsetDateTime.now();
            while(true) {
                if(OffsetDateTime.now().isAfter(t.plus(frequencyInMilliseconds, ChronoUnit.MILLIS))){
                    if(currentCapacity<capacity){
                        System.out.println("token added");
                        ++currentCapacity;
                    }
                    t=OffsetDateTime.now();
                }
            }
        }
    }
}

主课

public static void main(String[] args) {
        RateLimiter rl = new RateLimiterTokenBucket(10,5);
        Thread t = new Thread((Runnable) rl);
        t.start();
        while(true){
            if(rl.consume()) {
                System.out.println(OffsetDateTime.now()+" ---> true");
            }
        }
    }

刚开始

2023-04-29T19:30:54.685553+05:30 ---> true
token added

作为输出 两个线程 main 和 t1 仍在运行

java multithreading synchronization
1个回答
1
投票

run
方法的整个主体都在同步块中。实际上 always 是一个错误。在线程完全完成并且
run
方法返回之前,您不希望任何其他线程能够执行什么操作?

此外,

synchronized(currentCapacity)
看起来也是一个错误,因为您的程序将不同的对象分配给
currentCapacity
。当一个线程在
Integer(5)
上同步而另一个线程在
Integer(4)
上同步时,这意味着什么?如果作为一般规则,除非
synchronized(foo)
是一个
foo
变量,否则您可以避免犯这个错误。

另请注意:您的主线程在等待下一个令牌时
旋转

(即,它会消耗 CPU 时间)。这并非 always 坏事,但通常 如果您正在运行的主机没有保留专用于该线程的 CPU,并且有其他线程准备好-运行并等待轮到他们使用 CPU。

© www.soinside.com 2019 - 2024. All rights reserved.