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






原创粉丝点击