package Ġcom . chr is . bull se ye . common . utils Ċ Ċ import Ġorg . springframework . data . redis . core . String Redis Template Ċ import Ġorg . springframework . stereotype . Component Ċ import Ġorg . springframework . util . StringUtils Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ /** Ċ Ġ* Ġ@ author ĠChris Ċ Ġ* Ġ@ date Ġ 2 0 2 1 - 1 0 - 0 8 Ġ 1 0 : 1 3 Ċ Ġ*/ Ċ @ Component Ċ class ĠDistributed Lock Ġ{ ĊĊĠĠĠ Ġprivate Ġval ĠLOCAL _ MAP : ĠMutable Map < String , ĠString > Ġ= ĠHashMap () ĊĊĠĠĠ Ġprivate Ġvar Ġredis : ĠString Redis Template ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġval ĠLOCK _ VALUE Ġ= Ġ" locked " ĊĊĠĠĠ Ġfun ĠDistributed Lock ( redis Template : ĠString Redis Template ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġredis Ġ= Ġredis Template ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlock ( key : ĠString ?, Ġexpire Minutes : ĠInt ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġset nx Ġ= Ġredis !!. bound Value Ops ( LOCK _ VALUE Ġ+ Ġkey ). set If Absent ( LOCK _ VALUE ) ĊĠĠĠĠĠĠĠ Ġif Ġ( set nx !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġredis !!. expire ( LOCK _ VALUE Ġ+ Ġkey , Ġexpire Minutes . to Long (), ĠTimeUnit . MIN UTES ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġset nx ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmust Lock ( key : ĠString ?, Ġexpire Minutes : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġset nx Ġ= Ġredis !!. bound Value Ops ( LOCK _ VALUE Ġ+ Ġkey ). set If Absent ( LOCK _ VALUE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( set nx !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġredis !!. expire ( LOCK _ VALUE Ġ+ Ġkey , Ġexpire Minutes . to Long (), ĠTimeUnit . MIN UTES ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( 1 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . error ( e . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġunlock ( key : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġredis !!. delete ( LOCK _ VALUE Ġ+ Ġkey ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** * ĊĠĠĠĠ Ġ* ĠåĪĨ å¸ĥ å¼ı éĶģ åıª æī§è¡Į ä¸Ģæ¬¡ ä»»åĬ¡ ĊĠĠĠĠ Ġ* Ġ@ param Ġkey ĊĠĠĠĠ Ġ* Ġ@ param Ġexpire Minutes ĊĠĠĠĠ Ġ* Ġ@ param Ġcall Back ĊĠĠĠĠ Ġ* Ġ@ param Ġ< T > ĊĠĠĠĠ Ġ* Ġ@ return ĊĠĠĠ Ġ</ T > Ġ*/ ĊĠĠĠ Ġfun Ġ< T > Ġdo Action With Cancel ( key : ĠString , Ġexpire Minutes : ĠInt , Ġcall Back : ĠCall Back < T >): ĠT ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlock Key Ġ= Ġget Lock Key ( key ) ĊĠĠĠĠĠĠĠ Ġsynchronized ( lock Key !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! lock ( lock Key , Ġexpire Minutes )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . debug (" åĪĨå¸ĥ å¼ı ä»»åĬ¡ :${ lock Key } Ġrunning .. ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġcall Back . do Action () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . debug (" åĪĨå¸ĥ å¼ı ä»»åĬ¡ :${ lock Key } Ġfinish .. ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// æ¯ıæ¬¡ æī§è¡Į å®Į åĲİ , ä¼ ĳ çľ ł 1 0 s , ä¿Ŀè¯ģ å¤ļ åı° æľįåĬ¡åĻ¨ ä¸į éĩįå¤į æī§è¡Į ( ä¸»è¦ģ æİĴ éĻ¤ æĹ¶ å·® éĹ®é¢ĺ ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( 1 0 0 0 0 L ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . error (" åĪĨå¸ĥ å¼ı ä»»åĬ¡ , æī§è¡Į å®ĮæĪĲ åĲİ , ä¼ ĳ çľ ł 1 0 s å¼Ĥå¸¸ !!!! !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// unlock ( lock Key ); ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Lock Key ( key : ĠString ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġlock Key Ġ= ĠLOCAL _ MAP [ key ] ĊĠĠĠĠĠĠĠ Ġif Ġ( StringUtils . has Length ( lock Key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( LOCAL _ MAP ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlock Key Ġ= ĠLOCAL _ MAP [ key ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( StringUtils . has Length ( lock Key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOCAL _ MAP [ key ] Ġ= Ġkey ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlock Key Ġ= Ġkey ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġlock Key ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġ< T > Ġdo Action ( key : ĠString , Ġexpire Minutes : ĠInt , Ġcall Back : ĠCall Back < T >): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlock Key Ġ= Ġget Lock Key ( key ) ĊĠĠĠĠĠĠĠ Ġsynchronized ( lock Key !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmust Lock ( lock Key , Ġexpire Minutes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . debug (" åĪĨå¸ĥ å¼ı ä»»åĬ¡ :${ lock Key } Ġrunning .." Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġcall Back . do Action () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . debug (" åĪĨå¸ĥ å¼ı ä»»åĬ¡ :${ lock Key } Ġfinish .. ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġunlock ( lock Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** * ĊĠĠĠĠ Ġ* Ġ åĽŀè°ĥ æĸ¹æ³ķ ĊĠĠĠĠ Ġ* Ġ@ param Ġ< T > ĊĠĠĠ Ġ</ T > Ġ*/ ĊĠĠĠ Ġfun Ġinterface ĠCall Back < T > Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġdo Action (): ĠT ĊĠĠĠ Ġ} Ċ }