java非阻塞锁_Java多线程程序非阻塞式锁定实现

多线程程序的锁定已经有良好的支持,通常使用synchronized修饰一个方法或者一段代码。但是有一个问题,多个线程同时调用同一个方法的时候,所

有线程都被排队处理了。该被调用的方法越耗时,线程越多的时候,等待的线程等待的时间也就越长,甚至于几分钟或者几十分钟。对于Web等对反应时间要求很

高的系统来说,这是不可以接受的。本文就介绍一种自己实现的锁定方法,可以在没有拿到锁之后马上返回,告诉客户稍候重试。51Testing软件测试网"oq+O+]dQS

某一段程序同一时刻需要保证只能单线程调用,那么策略很简单,最先到的线程获取锁成功,在它释放之前其它线程都会获取失败。首先要构造一个全局的系统锁仓库,代码如下:X\Ik(?'d(~051Testing软件测试网5@tN/@,cb-r6Z:k

/*

c%sG{d0 * LockStore.java  2012-5-15

C:nwY w!J0 */51Testing软件测试网h1Ci%{)rb%?Z{

9ATheG,iV"Jt0import java.util.Date;

v8z}7@2x0import java.util.HashMap;51Testing软件测试网 S2S/l#|qK H

import java.util.Map;51Testing软件测试网M3`t)r/N.N+?~Q51Testing软件测试网$L;E"^\J2] t:l-?

/**

:t|EyRo0 * 公用的内存锁仓库. 分为获取锁和释放锁两种操作。

lLVx:E0 *51Testing软件测试网ELkG-T X~

* @version 1.0

\MaBo'R0 */51Testing软件测试网 f y$\in/x*n

public final class LockStore {51Testing软件测试网o@+Ta0Y3Yo

// volatile保证所有线程看到的锁相同

s

W;~C+}0 private static volatile Map locks = new HashMap();-O#Bj;qA.hL2sz051Testing软件测试网'd$va#^6@9B1\8};q

private LockStore() {,BFDz/l#{*K%t6k051Testing软件测试网OXT}A)Z _

}\LW3M)\$q\b0

B'|U6Y#Umv0/**

&B'`V3o5cc_$I-E0  * 根据锁名获取锁51Testing软件测试网)hsIz+G

*

K q2CR_0  * @param lockName

O3o0w;Ip6a Q*_#n~0  *            锁名51Testing软件测试网,|-}4Q!E/O6vH(x

* @return 是否锁定成功51Testing软件测试网't0L7m&EYhZ1p

*/

^5|s1hv?0 public synchronized static Boolean getLock(String lockName) {

C#^4h7{"O7T(m&R!hn^0  Boolean locked = false;\'[7\({$iO3K0

7QM)J6W4g*WO6N%`0if (StringUtils.isEmpty(lockName)) {

p

f-J5n\o~i0   throw new RuntimeException("Lock name can't be empty");

*G&D(p;AQe.R0  }w&XW"Mjd,\051Testing软件测试网Ka@#Ry:]

Date lockDate = locks.get(lockName);51Testing软件测试网|

n{? M{u9Gh

if (lockDate == null) {

2ouv|f0   locks.put(lockName, new Date());51Testing软件测试网!RQ1C$v8W

locked = true;

3n.o"zU

A0  }51Testing软件测试网b~)G"S8?3z5Pc&}

#m6xK/f"Z:J&E)|,Eb0return locked;

0BP;~pMP2McI0 }h;HWU[DK-L051Testing软件测试网&l/?vE9~.D%Xn)|

/**

([C

z\ jg0  * 根据锁名释放锁

naw"{,A |0  *

)~!{r5OHj)`!t0  * @param lockName

Q)i-OI9BO)Q,D[yk0  *            锁名51Testing软件测试网jwZ3]qs

*/51Testing软件测试网&Igqsh7u]+T

public synchronized static void releaseLock(String lockName) {51Testing软件测试网dvz6li+N

if (StringUtils.isEmpty(lockName)) {51Testing软件测试网?:^m#~V~b!j

throw new RuntimeException("Lock name can't be empty");

og(lB [d5V,`pj0  }%x&q~C;T(K}0

/Kr"Xj x#}@0Date lockDate = locks.get(lockName);51Testing软件测试网9g$pQ0NFdU1K

if (lockDate != null) {

N7\gWo7Rjr)[ z0   locks.remove(lockName);51Testing软件测试网`#eI{1eJ1Y Ob

}51Testing软件测试网6N*gZ${|!B

}51Testing软件测试网H,{4v)@5~d

;M

Z[XU*L0/**

e6dqs']#AFr1]:A0  * 获取上次成功锁定的时间51Testing软件测试网t6p$Nl,vo"@n!Gz

*51Testing软件测试网jbE5A[s3cl6L9@

* @param lockName

a_(RS,ll;Z

}%m,[0  *            锁名

&t2f%cN'Y;f5p4Ao)Sw0  * @return 如果还没有锁定返回NULL

+^?MW3Vb0  */

%IJZ3_$gE\6p0 public synchronized static Date getLockDate(String lockName) {51Testing软件测试网7_9V/o(vEH

if (StringUtils.isEmpty(lockName)) {51Testing软件测试网;zJ4Y@&H2f;q ^0M

throw new RuntimeException("Lock name can't be empty");

uaq3|1l-L'tihQ0  }51Testing软件测试网V rs1Bh\9h`6d{

j7k

x;m3ocGg1S y}a#?uo0Date lockDate = locks.get(lockName);51Testing软件测试网3u5K6e \;U+X;h51Testing软件测试网!r6W"p.kI%T[8Q:]X1D

return lockDate;

3L;a!Hf(me0 }

kTo$k'm&J4a3z$UU.]0}51Testing软件测试网9BybL!{}3b51Testing软件测试网(`3S!@n&r

锁仓库提供了三个方法,都是静态的,可以在系统内任意地方调用。 这里要提的是锁名,是一个字符串,可以随意构造,通常是需要锁定的方法名+需要单线程处理的标识。比如部门ID。这样不同的部门有不同的锁,独立运行,同一个部门同一个锁,单线程处理。具体使用如下:t

N\zkIA0

v5o!mY7q {9_5}09u2D1F@`cRW!I0ElQP}Q0/*51Testing软件测试网e%kN$FLt@.[z

* LockTest.java  2012-6-1951Testing软件测试网K9Zk*IgZ8dT

*/:yW spi;R0Icf!c051Testing软件测试网7KG MZw,X

import java.text.SimpleDateFormat;

n~X&Y.x

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值