In
http://blog.csdn.net/houjixin/article/details/45222081 or
http://houjixin.blog.163.com/blog/static/3562841020153233201796/
The speed limiter implemented in the, need to maintain a container to record the time of each visit, each new request for resources by calculating the difference between the first two time in the container and the number of accesses in the container to determine whether overspeed, in fact, this implementation has two drawbacks:
(1) Only compare the average speed, no comparison of instantaneous velocity, if the speed limiter limit the maximum access 1000 times per second, if the first 500 milliseconds access 999 times, after 500 milliseconds to access once, this situation can not be judged;
(2) The implementation method is more complicated.
Therefore, the implementation of this article is based on the interval time limit method, its basic idea is: if the speed limiter limit maximum access rate of 100 per second, it can be considered that the adjacent two times the interval of access can not be less than 10 milliseconds, therefore, each access to the resource only need to compare with the last access time interval, The relevant implementation code is:
Package Test_tmp;import Java.util.concurrent.Semaphore;//Use two consecutive time intervals to determine the use of adjacentImport Java.util.concurrent.atomic.AtomicLong; Public classspeedlimiter2<t> {Private Static LongInit_time =0;//Parameter maxusedfrequency, which indicates that the maximum access speed for resource resource is maxusedfrequency times per second Public SpeedLimiter2(intMaxusedfrequency, T Resource) { This. resource = resource; This. Interval = +/maxusedfrequency;//Indicates the access interval between two consecutive times in millisecondsM_semaphore =NewSemaphore (maxusedfrequency); Lastusedtime =NewAtomiclong (Init_time); }PrivateAtomiclong Lastusedtime =NULL;Private LongInterval =0;maximum time between//two requests for resources PrivateT resource =NULL;//Use semaphores to restrict access to resources PrivateSemaphore M_semaphore =NULL;//Synchronize request Resources PublicSynchronized TConsume() {LongCurtime = System.currenttimemillis ();LongCurinterval = Curtime-lastusedtime.Get();if(Curinterval < interval) {//Request speed is too fast, need a restSystem. out. println (String.Format ("+++++++++++++++need sleep:interval:%d-%d =%d", Interval, Curinterval, (Interval-curinterval))); Safesleep (Interval-curinterval); }//Request Resources Try{M_semaphore.acquire (); }Catch(Interruptedexception e) {E.printstacktrace ();return NULL; } lastusedtime.getandset (System.currenttimemillis ());//Record the time when the application resource was successful returnResource } Public void Returnresource() {System. out. println ("-------------Reclaim a resource"); M_semaphore.release (); }Private void Safesleep(LongSleeptime) {Try{Thread.Sleep (sleeptime); }Catch(Interruptedexception e) {E.printstacktrace (); } }}
The code for the associated test thread is:
Package test_tmp; Public class TestSpeedLimitedThread2<T> extends Thread {speedlimiter2<t> limiter =NULL; PublicTestSpeedLimitedThread2 (speedlimiter2<t> limiter) { This. limiter = limiter; } Public voidRun () {Longi =0; while(true) {T Tmpresource = Limiter.consume (); System.out.println ("Thread ID:"+ CurrentThread (). GetId () +" : "+ (i+1) +": The resource has been acquired:"+ Tmpresource); i++;Try{Thread.Sleep (Ten); }Catch(Interruptedexception e) {//TODO auto-generated catch blockE.printstacktrace (); } limiter.returnresource (); } }}
The relevant main test code is:
PublicStaticvoidTestspeedlimiter () {StringResource= "MyResource"; SpeedLimiter2<String>Test= NewSpeedLimiter2<String>( -, resource); TestSpeedLimitedThread2<String>TestThread1= NewTestSpeedLimitedThread2<String>(test); TestThread1.Start (); TestSpeedLimitedThread2<String>TestThread2= NewTestSpeedLimitedThread2<String>(test); TestThread2.Start (); TestSpeedLimitedThread2<String>TestThread3= NewTestSpeedLimitedThread2<String>(test); TestThread3.Start (); try {TestThread1.Join(); TestThread2.Join(); TestThread3.Join(); } catch (Interruptedexception e) {E.Printstacktrace (); } }
Java implementation of a simple speed limiter [2]