ReentrantLock
- ReentrantLock是JDK方法,需要手动声明上锁和释放锁,因此语法相对复杂些;如果忘记释放锁容易导致死锁
- ReentrantLock具有更好的细粒度,可以在ReentrantLock里面设置内部Condititon类,可以实现分组唤醒需要唤醒的线程
- RenentrantLock能实现公平锁
Synchronized
- Synchoronized语法上简洁方便
- Synchoronized是JVM方法,由编辑器保证枷锁和释放
案例:模拟多线程请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
//获取价格--synchronized @GetMapping("/getPrice") public synchronized String getPrice(){ Object price = redisUtil.get("price"); int i = Integer.parseInt(price.toString())-1; System.out.println(i); redisUtil.set("price",i); return "设置价格成功+"+i+""; } //<strong>ReentrantLock锁</strong> @GetMapping("/getLockPrice") public String getLockPrice(){ int i = 0; try { lock.lock(); Object price = redisUtil.get("price"); i = Integer.parseInt(price.toString())-1; System.out.println(i); redisUtil.set("price",i); } catch (NumberFormatException e) { e.printStackTrace(); }finally { lock.unlock(); } return "设置价格成功+"+i+""; } |
案例二:自己开启的进程,这只用到了Lock锁。以及线程里面使用SpringContextHolder获取RedisUtil的工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
package com.java; import com.utils.RedisUtil; import com.utils.SpringContextHolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @Controller @RequestMapping("/ManyThread") public class MyReenrantLock implements Runnable { private Lock lock=new ReentrantLock(); /** * 日志对象 */ protected Logger logger = LoggerFactory.getLogger(getClass()); @Override public void run() { lock.lock(); int i=0; RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class); Object price = redisUtil.get("price"); i = Integer.parseInt(price.toString())-1; System.out.println(i); redisUtil.set("price",i); logger.warn(Thread.currentThread().getName()); System.out.println("当前线程名: "+ Thread.currentThread().getName()+" ,i = "+i); lock.unlock(); } //测试多线程 @RequestMapping("/getManyThread") public void getManyThread() { MyReenrantLock myReenrantLock = new MyReenrantLock(); Thread thread = new Thread(myReenrantLock); Thread thread1 = new Thread(myReenrantLock); Thread thread2 = new Thread(myReenrantLock); Thread thread3 = new Thread(myReenrantLock); thread.start(); thread1.start(); thread2.start(); thread3.start(); } } |