使用lock解决线程安全问题

业务背景:多个话务员需要为客户回退有问题的套餐金额,话务员共享一个退费的总额度,每次退费会对总额度做减操作,额度消耗完,话务员需要重新申请资源。这里会发生一个问题,话务员们同时操作这个额度时,就出现了线程安全的问题,所以,应该为这个操作步骤添加锁,谁先拥有这个锁,谁就优先操作这个额度,很多人一下子想到了synchronized, 确实可以利用synchronized关键字来同步这个操作过程,防止超额问题,然而会出现另外一个问题,synchronized是不能获取锁的状态,线程一旦拿不到锁会一直等待,这会让系统出现阻塞问题,因此,想到了可以 获取锁状态的方案,使用lock的trylock,尝试获取锁,如果拿到锁就做减操作,如果没拿是否就放弃操作了呢,这里可以引入重试机制,如果在重试次数内拿到锁就做减操作,如果没拿到再放弃,返回系统繁忙。以下是相关demo

public class Lock1 {

	private volatile static int count = 100 ;
	static  Lock lock = new ReentrantLock() ;
	
	public static void reduce() {
		 boolean  islock = lock.tryLock();
		try {
		//重试次数
		int retry = 3 ;
		while(!islock) {
			if(retry == 0) break ;
			Thread.sleep(100);
			islock = lock.tryLock();
			System.out.println(Thread.currentThread()+":retry"+retry);
			retry-- ;
		}
		if(islock == true) {
	        count--;
			System.out.println(count);
		}else {
			System.out.println("系统繁忙!!!");
		}

		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			if(islock) lock.unlock();
		}
	}
	
public class Thread1 implements Runnable{

	public void run() {
      Lock1.reduce();		
	}
	
	
	public static void main(String[] args) {
		for(int i=0 ; i<100 ;i++) {
			Thread t = new Thread(new Thread1());
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			t.start();
		}
	}

}

代码执行结果:
99
98
97
96
95
94
93
92
91
90
89
88
87
86
85
84
83
82
81
80
79
78
77
76
75
74
73
72
71
70
69
68
67
66
65
64
63
62
61
60
59
58
57
56
55
54
53
52
51
50
49
48
47
46
45
44
43
42
41
40
39
38
37
36
35
34
33
32
31
30
Thread[Thread-1,5,main]:retry3
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
Thread[Thread-71,5,main]:retry3
0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值