因为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个结果了。