一个简单限速器的java实现[2]

在 或者 中实现的限速器,需要内部维持一个容器来记录每次访问的时间,,在每次新请求资源时通过计算容器中首尾两个时间的差值以及容器中的访问次数来确定是否超速,其实这种实现方法有两个缺点: (1)只比较了平均速度,没有比较瞬时速度,假如限速器限制每秒钟最多访问1000次,如果前500毫秒访问了999次,后500毫秒就访问一次,这种情况就无法进行判断; (2)实现方法比较复杂。 因此,在本文中实现的是基于间隔时间的限速方法,它的基本思路为:假如限速器限制的最大访问速度为每秒100,则可认为,相邻两次访问的间隔时间不能小于10毫秒,因此,在每次访问资源时只需要比较与上次访问的时间间隔即可,相关实现代码为:

package test_tmp;import java.util.concurrent.Semaphore;//使用两次相邻使用的间隔时间进行判断import java.util.concurrent.atomic.AtomicLong;public class SpeedLimiter2<T> {INIT_TIME = 0;(int maxUsedFrequency, T resource){this.resource = resource;this.interval = 1000 / maxUsedFrequency;//表示相邻两次之间的访问间隔时间(毫秒)m_semaphore = new Semaphore(maxUsedFrequency);lastUsedTime = new AtomicLong(INIT_TIME);}private AtomicLong lastUsedTime = null;T resource = null;//用信号量来限制资源的访问private Semaphore m_semaphore = null;//同步申请资源public synchronized T consume(){long curTime = System.currentTimeMillis();long curInterVal = curTime – lastUsedTime.get();if(curInterVal < interval){//请求速度太快了,需要休息一下System.out.println(String.format(“+++++++++++++++need sleep: interval:%d – %d = %d”,interval, curInterVal, (interval – curInterVal)));safeSleep(interval – curInterVal);}//申请资源try {m_semaphore.acquire();} catch (InterruptedException e) {e.printStackTrace();return null;}lastUsedTime.getAndSet(System.currentTimeMillis());//记录下申请资源成功的时间return resource;}(){System.out.println(“————-回收一个资源”);m_semaphore.release();}(long sleepTime){try{Thread.sleep(sleepTime);}catch (InterruptedException e){e.printStackTrace();}}}

相关的测试线程的代码为:

package test_tmp;<T> extends Thread {SpeedLimiter2<T> limiter = null;public TestSpeedLimitedThread2(SpeedLimiter2<T> limiter){this.limiter = limiter;}public void run(){long i = 0;while(true){T tmpResource = limiter.consume();System.out.println(“thread id: ” + currentThread().getId() + ” : ” +(i+1) + “: 已经获取到资源:” + tmpResource);i++;try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}limiter.returnResource();}}}

相关的主测试代码为:

public static void testSpeedLimiter(){String resource = “myresource”;SpeedLimiter2test (50, resource);TestSpeedLimitedThread2testThread1 (test);testThread1.start();TestSpeedLimitedThread2testThread2 (test);testThread2.start();TestSpeedLimitedThread2testThread3 (test);testThread3.start();try {testThread1.join();testThread2.join();testThread3.join();} catch (InterruptedException e) {e.printStackTrace();}}

或者在河边放下一盏写着心愿的河灯,祝愿一切安好。

一个简单限速器的java实现[2]

相关文章:

你感兴趣的文章:

标签云: