Java Implementation of a simple speed limiter
In the daily development process, resource usage frequency is often limited. For example, an interface can only be called 300 times per second, or a resource object can only use 300 times per second, the following is a java implementation of a simple speed limiter. It can be used to access a resource for several times (within milliseconds). The specific implementation code is as follows:
Package test_tmp; import java. util. concurrent. concurrentincludeque; import java. util. concurrent. Semaphore; public class SpeedLimiter
{// The two parameters maxUsedLimited and timeLimited are used to limit the access speed, indicating that only maxUsedLimited times of public SpeedLimiter (int maxUsedLimited, int timeLimited, T resource) can be used to limit the access speed within milliseconds) {this. maxUsedLimited = maxUsedLimited; this. timeLimited = timeLimited; this. resource = resource; m_semaphore = new Semaphore (maxUsedLimited * 1000/timeLimited);} concurrentincludeque
StatisticsInfo = new concurrentincludeque
(); T resource = null; // The following two parameters are used to limit the access speed. private int maxUsedLimited; private int timeLimited; // The Statistical duration is 1000 milliseconds, that is, 1 second // use semaphores to restrict resource access. private Semaphore m_semaphore = null; public synchronized T consume () {if (statisticsInfo. size ()> = maxUsedLimited) {// you have used the time record long ti = statisticsInfo. getLast ()-statisticsInfo. getFirst (); if (ti <timeLimited) {// It has exceeded the limit, that is, the number of times has reached, but the time has not reached STATISTICS_TIME, which indicates that the application is too fast, when the difference is, the sleep time is used. System. out. println ("------------- resource access is restricted. Currently," + ti + "has been accessed in milliseconds" + statisticsInfo. size () + "secondary resource"); safeSleep (timeLimited-ti);} statisticsInfo. removeFirst (); // The total number of times has arrived. Delete the oldest time every time} // apply first and record the time. try {m_semaphore.acquire ();} catch (InterruptedException e) {e. printStackTrace ();} statisticsInfo. add (System. currentTimeMillis (); return resource;} public void returnResource () {System. out. println ("------------- reclaim a resource. Available resources:" + m_semaphore.drainPermits (); m_semaphore.release ();} private void safeSleep (long sleepTime) {try {Thread. sleep (sleepTime);} catch (InterruptedException e) {e. printStackTrace ();}}}
The following is an example of using the speed limiter:
The first is the code of the test thread:
Package test_tmp; public class TestSpeedLimitedThread
Extends Thread {SpeedLimiter
Limiter = null; public TestSpeedLimitedThread (SpeedLimiter
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) + ": resources obtained:" + tmpResource); I ++; try {Thread. sleep (10);} catch (InterruptedException e) {// TODO Auto-generated catch block e. printStackTrace ();} limiter. returnResource ();}}}
The code for the main test function is as follows:
public static void testSpeedLimiter() { String resource = "myresource"; SpeedLimiter
test = new SpeedLimiter
(50, 1000, resource); TestSpeedLimitedThread
testThread1 = new TestSpeedLimitedThread
(test); testThread1.start(); TestSpeedLimitedThread
testThread2 = new TestSpeedLimitedThread
(test); testThread2.start(); TestSpeedLimitedThread
testThread3 = new TestSpeedLimitedThread
(test); testThread3.start(); try { testThread1.join(); testThread2.join(); testThread3.join(); } catch (InterruptedException e) { e.printStackTrace(); } }