jedis之cas操作
来源:互联网 发布:淘宝一个店铺几个类目 编辑:程序博客网 时间:2024/06/05 00:50
我们都知道,可以使用multi和watch等redis原生命令实现cas效果。接下来,我们通过jedis来实现一次。
我们模拟一个多线程自增的操作。
1、使用redis的incr命令实现:
package cn.edu.nuc.MyTestSimple.redis;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.atomic.AtomicInteger;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;public class RedisTest {private static final String redisHost = "toutiao.jylt.qiyi.redis"; private static final int port = 19822; private static JedisPoolConfig config; private static JedisPool pool; private static ExecutorService service; private static int ThLeng=10; private static CountDownLatch latch; private static String key = "kevilniu_count"; private static AtomicInteger Countor = new AtomicInteger(0); static{ //利用Redis连接池,保证多个线程利用多个连接,充分模拟并发性 config = new JedisPoolConfig(); config.setMaxIdle(10); config.setMaxWaitMillis(1000); config.setMaxTotal(30); pool = new JedisPool(config, redisHost, port,1000,"hcmK9vzMUIH5dqGkLnA5D"); //利用ExecutorService 管理线程 service = Executors.newFixedThreadPool(10); //CountDownLatch保证主线程在全部线程结束之后退出 latch = new CountDownLatch(ThLeng); } public static void main(String args[]){ int ThLeng = 100; String ThreadNamePrefix = "thread-"; Jedis cli = pool.getResource(); cli.del(key);//先删除既定的key cli.set(key, String.valueOf(0));//设定默认值 for(int i =0;i<ThLeng;i++){ Thread th = new Thread(new TestThread(pool)); th.setName(ThreadNamePrefix+i); service.submit(th); } service.shutdown(); try { latch.await(); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("------------------------------all sub thread sucess"); System.out.println("countor is "+Countor.get()); String countStr = cli.get(key); System.out.println(countStr); } public static class TestThread implements Runnable { volatile boolean flag = true; private Jedis cli; private JedisPool pool; public TestThread(JedisPool pool) { cli = pool.getResource(); this.pool = pool; } public void run() { try{ for (int i = 0; i < 100; i++) { actomicAdd(); } }catch(Exception e){ pool.returnBrokenResource(cli); } finally{ pool.returnResource(cli); latch.countDown(); } } public void actomicAdd(){ Long incrBy = cli.incrBy(key, 1); //System.out.println(Thread.currentThread().getName()+","+incrBy); } }}输出:
10000
2、使用redis的cas语义完成:
package cn.edu.nuc.MyTestSimple.redis;import java.util.List;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.atomic.AtomicInteger;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;import redis.clients.jedis.Transaction;public class RedisWatchLock {private static final String redisHost = "toutiao.jylt.qiyi.redis"; private static final int port = 19822; private static JedisPoolConfig config; private static JedisPool pool; private static ExecutorService service; private static int ThLeng=10; private static CountDownLatch latch; private static AtomicInteger Countor = new AtomicInteger(0); static{ //利用Redis连接池,保证多个线程利用多个连接,充分模拟并发性 config = new JedisPoolConfig(); config.setMaxIdle(10); config.setMaxWaitMillis(1000); config.setMaxTotal(30); pool = new JedisPool(config, redisHost, port,1000,"hcmK9vzMUIH5dqGkLnA5D"); //利用ExecutorService 管理线程 service = Executors.newFixedThreadPool(10); //CountDownLatch保证主线程在全部线程结束之后退出 latch = new CountDownLatch(ThLeng); } public static void main(String args[]){ int ThLeng = 10; String ThreadNamePrefix = "thread-"; Jedis cli = pool.getResource(); cli.del("redis_inc_key");//先删除既定的key cli.set("redis_inc_key", String.valueOf(0));//设定默认值 for(int i =0;i<ThLeng;i++){ Thread th = new Thread(new TestThread(pool)); th.setName(ThreadNamePrefix+i); service.submit(th); } service.shutdown(); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("------countor is "+Countor.get()); String countStr = cli.get("redis_inc_key"); System.out.println(countStr); } public static class TestThread implements Runnable { private String incKeyStr = "redis_inc_key"; private Jedis cli; private JedisPool pool; public TestThread(JedisPool pool) { cli = pool.getResource(); this.pool = pool; } public void run() { try{ actomicAdd(); }catch(Exception e){ pool.returnBrokenResource(cli); } finally{ pool.returnResource(cli); latch.countDown(); } } public void actomicAdd(){ while (true) { try { cli.watch(incKeyStr); String countStr = cli.get(incKeyStr); int countInt = Integer.parseInt(countStr); Transaction tx = cli.multi(); tx.set(incKeyStr, String.valueOf(countInt + 1)); List<Object> list = tx.exec(); //如果事务失败了exec会返回null if(list==null){ continue; } else{ System.out.println(Thread.currentThread().getName()+","+(countInt + 1)); break; } } catch (Exception e) { } } Countor.incrementAndGet(); } }}输出:
pool-1-thread-1,1pool-1-thread-3,2pool-1-thread-5,3pool-1-thread-6,4pool-1-thread-8,5pool-1-thread-4,6pool-1-thread-7,7pool-1-thread-10,8pool-1-thread-2,9pool-1-thread-9,10------countor is 1010
阅读全文
0 0
- jedis之cas操作
- redis 之 jedis操作
- Java之CAS操作
- java并发之CAS操作
- java操作redis之jedis篇
- redis客户端之jedis 操作工具类
- 11.Redis之使用Jedis操作
- redis客户端之jedis 操作工具类
- jedis操作
- Jedis操作
- jedis 操作
- java多线程(2)之CAS操作
- CAS操作
- CAS操作
- CAS操作
- CAS操作
- CAS操作
- CAS操作
- Python字符串的一些操作(截取+替换+查找+分割)
- hdu 3068
- 给Recyclerview添加下划线
- Jenkins Pipeline 常用操作
- ue4 fuck
- jedis之cas操作
- WritableResource写文件ClassPathResource读文件
- docker目录挂载
- android wifi驱动移植
- 【安全牛学习笔记】主动信息收集-发现(三)
- HDOJ1002
- Linux查找含有某字符串的所有文件
- HBase命令行操作
- HotSpot虚拟机对象探秘