package qc.distribute.lock; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.locks.InterProcessMutex; import org.apache.curator.retry.RetryOneTime; import org.redisson.Redisson; import org.redisson.RedissonRedLock; import org.redisson.api.RLock; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; /** * 此处测试了jvm单机锁 ReentrantLock,RedissonRedLock,Zk可重入公平锁 * - 单机锁ReentrantLock {@link #reentrant} * - redis分布式锁 {@link #redisson} * - zk分布式锁 {@link #curator} * * - 模拟用户多次点击 - 提示用户重复提交 * @author QuCheng on 2020/7/9. */ @RestController @RequestMapping("dist/lock") public class LockController { @Resource private Redisson redisson; ReentrantLock rLock = new ReentrantLock(); @GetMapping("/reentrant") public String reentrant(String lockname) { System.out.println(Thread.currentThread().getName()); if (rLock.tryLock()) { try { System.out.println("reentrant单机锁"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { rLock.unlock(); } } else { throw new RuntimeException("不要闹"); } return lockname; } @GetMapping("/redisson") public String redisson(String lockname) { RLock rLock1 = redisson.getLock(lockname); // 此处应传入多个redis实例 RedissonRedLock rLock = new RedissonRedLock(rLock1); if (rLock.tryLock()) { try { System.out.println("redisson拿到锁执行业务"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { rLock.unlock(); } return lockname; } else { return "点慢点"; } } CuratorFramework client = CuratorFrameworkFactory.newClient("39.106.39.249:2181", new RetryOneTime(1000)); { // 为了测试方便 - 直接在此处引用zk,实际可使用配置项注入bean使用 client.start(); } @GetMapping("/curator") public String curator(String lockname) { InterProcessMutex lock = new InterProcessMutex(client, "/d-lock/" + lockname); try { if (lock.acquire(0, TimeUnit.MILLISECONDS)) { try { System.out.println("拿到锁执行业务"); Thread.sleep(10000); return lockname; } catch (InterruptedException e) { e.printStackTrace(); } finally { try { lock.release(); } catch (Exception e) { System.out.println("释放锁失败"); } } } } catch (Exception e) { System.out.println("拿锁失败"); } return "点慢点"; } }