博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis做分布式无锁CAS的问题
阅读量:6671 次
发布时间:2019-06-25

本文共 3129 字,大约阅读时间需要 10 分钟。

hot3.png

因为Redis本身是单线程的,具备原子性,所以可以用来做分布式无锁的操作,但会有一点小问题。

public interface OrderService {    public String getOrderNo();}
public class OrderRedisServiceImpl implements OrderService {    static JedisPool jedisPool;    static {        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();        jedisPool = new JedisPool(jedisPoolConfig,"XXX.XXX.XXX.XXX",6379,0);    }    @Override    public String getOrderNo() {        try {            Jedis jedis = jedisPool.getResource();            SimpleDateFormat date = new SimpleDateFormat("YYYYMMDDHHMMSS");            return date.format(new Date()) + jedis.incr("order_keys");        }finally {            jedisPool.close();        }    }}

redis实现的接口

public class OrderTask implements Runnable {    private CountDownLatch latch;    private OrderService orderService;    public OrderTask(CountDownLatch latch,OrderService orderService) {        this.latch = latch;        this.orderService = orderService;    }    @Override    public void run() {        try {            latch.await();        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.printf("线程名%s订单号:%s\n",Thread.currentThread().getName(), orderService.getOrderNo());    }}

线程任务类

public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool(); final CountDownLatch latch = new CountDownLatch(1); OrderService orderService = new OrderRedisServiceImpl(); for (int i = 0;i < 10;i++) { service.submit(new OrderTask(latch,orderService)); } latch.countDown(); service.shutdown();}

运行结果如下

线程名pool-2-thread-5订单号:20180719623079251

线程名pool-2-thread-3订单号:20180719623079252
线程名pool-2-thread-4订单号:201807196230710755
线程名pool-2-thread-7订单号:201807196230710754
线程名pool-2-thread-9订单号:201807196230710756
线程名pool-2-thread-2订单号:201807196230710757
线程名pool-2-thread-8订单号:201807196230710753
线程名pool-2-thread-1订单号:201807196230730458

他只跑出了8个结果,我们的确是运行了10次,由此我们记得jedis的默认最大连接数为8,所以只要我们的运行的线程数大于8,也只会跑出8个结果。

所以我们要修改如下

public class OrderRedisServiceImpl implements OrderService {    static JedisPool jedisPool;    static {        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();        jedisPoolConfig.setMaxIdle(-1);        jedisPoolConfig.setMaxTotal(-1);        jedisPool = new JedisPool(jedisPoolConfig,"XXX.XXX.XXX.XXX",6379,0);    }    @Override    public String getOrderNo() {        try {            Jedis jedis = jedisPool.getResource();            SimpleDateFormat date = new SimpleDateFormat("YYYYMMDDHHMMSS");            return date.format(new Date()) + jedis.incr("order_keys");        }finally {            jedisPool.close();        }    }}

把redis连接池的最大连接数增大,运行结果如下

线程名pool-2-thread-4订单号:201807196230758759

线程名pool-2-thread-5订单号:201807196230758860
线程名pool-2-thread-2订单号:201807196230758961
线程名pool-2-thread-3订单号:201807196230758862
线程名pool-2-thread-7订单号:201807196230758763
线程名pool-2-thread-8订单号:201807196230758764
线程名pool-2-thread-10订单号:201807196230758765
线程名pool-2-thread-6订单号:201807196230758866
线程名pool-2-thread-1订单号:201807196230758768
线程名pool-2-thread-9订单号:201807196230759067

这一次就是10个结果了。

转载于:https://my.oschina.net/u/3768341/blog/1854578

你可能感兴趣的文章
【首发】OpsWorld大会主题分享《抽丝剥茧之MySQL疑难杂症排查》
查看>>
《Lua游戏开发实践指南》一3.3本章小结
查看>>
《Android程序设计》一3.2 活动、意图和任务
查看>>
2016 机器学习之路:一年从无到有掌握机器学习
查看>>
红杉计越:AI、大数据、SaaS、云计算为何在中国一体迸发?
查看>>
阿里张勇:数据驱动的透明是平台治理的基础
查看>>
思科零售业解决方案助力企业提升服务与客户体验
查看>>
《哈利·波特》出版二十周年,教大家用神经网络写咒语!
查看>>
希捷发布全球首款2TB M.2 SSD固态硬盘
查看>>
《Java语言导学(原书第6版)》一一3.4 控制流语句
查看>>
银行如何通过大数据预测并防止用户流失?
查看>>
论各类BI工具的“大数据”特性
查看>>
博科15亿美元收购WLAN企业Ruckus
查看>>
EMC挑战全闪存极限
查看>>
着力大数据与大生态融合 贵阳第一个示范性公园开园
查看>>
ActiveMQ - JMS,Transport,Persistence
查看>>
互联网大数据支撑生态银行建设
查看>>
生态城年内开建智慧城市
查看>>
解密国产大数据法律应用服务平台
查看>>
打造智慧城市新风貌 嘉兴市推广应用万盏LED路灯
查看>>