生成唯一性订单约束的四种方式锁(对象锁,类锁、分布式redis锁,分布式Zookeeper锁)

1.对象锁

package com.peopleyun.lock;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2018/1/3.
 */
public class ObjectLock {
    public static int  num  = 0;
    static ExecutorService executorService = Executors.newFixedThreadPool(2);

    public static void main(String[] args) {

        final OrderLock orderLock = new OrderLock();
        executorService.execute(new Runnable() {
            @Override
            public void run() {

                for (int i  = 0; i < 100000 ; i ++ ){
                    System.out.println(Thread.currentThread().getName() + " "  + orderLock.setInCrease());
                }
            }
        });

        executorService.execute(new Runnable() {
            @Override
            public void run() {

                for (int i  = 0; i < 100000 ; i ++ ){
                    System.out.println(Thread.currentThread().getName() + " "  + orderLock.setInCrease());
                }
            }
        });



        try {
            executorService.shutdown();
            executorService.awaitTermination(100, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

       System.out.println(num);
    }



    static  class  OrderLock{
        public   synchronized String  setInCrease(){
            num ++;
            return getStringDateShort() + num;  //返回订单ID
        }
    }

    public static String getStringDateShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateString = formatter.format(currentTime);
        return dateString;
    }
}

2.类锁生成唯一性ID

package com.peopleyun.lock;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2018/1/3.
 */
public class ObjectLock {
    public static int  num  = 0;
    static ExecutorService executorService = Executors.newFixedThreadPool(2);

    public static void main(String[] args) {


        executorService.execute(new Runnable() {
            @Override
            public void run() {
                OrderLock orderLock = new OrderLock();
                for (int i  = 0; i < 100000 ; i ++ ){
                    System.out.println(Thread.currentThread().getName() + " "  + orderLock.setInCrease());
                }
            }
        });

        executorService.execute(new Runnable() {
            @Override
            public void run() {
                OrderLock orderLock = new OrderLock();
                for (int i  = 0; i < 100000 ; i ++ ){
                    System.out.println(Thread.currentThread().getName() + " "  + orderLock.setInCrease());
                }
            }
        });



        try {
            executorService.shutdown();
            executorService.awaitTermination(100, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

       System.out.println(num);
    }



    static  class  OrderLock{
        public  static synchronized String  setInCrease(){
            num ++;
            return getStringDateShort() + num;  //返回订单ID
        }
    }

    public static String getStringDateShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateString = formatter.format(currentTime);
        return dateString;
    }
}

3.  分布式Redis锁

package com.peopleyun.redisLock;

import redis.clients.jedis.Jedis;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2017/12/6.
 */
public class RedisLock {
    public static int  num  = 0;
    static ExecutorService executorService = Executors.newFixedThreadPool(2);
    private static  String ip = "10.1.15.53";
    private static  int port = 6379;
    private static  Jedis jedis;
    private static  String lock = "lock";
    private static  String lockvalue = "lockvalue";




    public static void main(String[] args) {
        
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                Jedis jedis =  new Jedis(ip ,port,3000);
                JedisLock jedisLock = new JedisLock(jedis);
                for (int i  = 0; i < 100000 ; i ++ ){
                    if(jedisLock.lock(10000,1)){
                        num++;
                        System.out.println(Thread.currentThread().getName() + " "  + getStringDateShort() + " " + num);
                    }
                    jedisLock.unlock();
                }
            }
        });



        executorService.execute(new Runnable() {
            @Override
            public void run() {
                Jedis jedis =  new Jedis(ip ,port,3000);
                JedisLock jedisLock = new JedisLock(jedis);
                for (int i  = 0; i < 100000 ; i ++ ){
                    if(jedisLock.lock(10000,1)){
                        num++;
                        System.out.println(Thread.currentThread().getName() + " "  + getStringDateShort() + " "+ num);
                    }
                    jedisLock.unlock();
                }
            }
        });



        try {
            executorService.shutdown();
            executorService.awaitTermination(100, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }





    }


    static class JedisLock{

        Jedis jedis;
        JedisLock(Jedis jedis){
            this.jedis = jedis;
            jedis.del(lock);//直接删除
        }
        /* 加锁
        * 使用方式为:
                * lock();
        * try{
            *    executeMethod();
            * }finally{
            *   unlock();
            * }
        *
        * @param expire 设置锁超时时间
        * @return 成功 or 失败
        */
        public boolean lock(long timeout,int expire){
            long nanoTime = System.nanoTime();

            try {
                //在timeout的时间范围内不断轮询锁
                while (true) {
                    //锁不存在的话,设置锁并设置锁过期时间,即加锁
                    if (jedis.setnx(lock, lockvalue) == 1L) {
                        jedis.expire(lock, expire);//设置锁过期时间是为了在没有释放
                        //锁的情况下锁过期后消失,不会造成永久阻塞
                        break;
                    }else {
                        System.out.println("出现锁等待");
                        //短暂休眠,避免可能的活锁
                        Thread.sleep(10);
                    }

                }

            } catch (Exception e) {
                jedis =  new Jedis(ip ,port,3000);
                e.printStackTrace();
                throw new RuntimeException("locking error",e);
            }
               return true;
        }


        public void unlock(){
            try {
                jedis.del(lock);//直接删除
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public static String getStringDateShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateString = formatter.format(currentTime);
        return dateString;
    }
}

4.  Zookeeper分布式锁


package com.peopleyun.lock;

import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import redis.clients.jedis.Jedis;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2017/12/6.
 */
public class ZkClientLock {

    private static String lock = "/lock/lock33";

    private static ZkClient zkClient;

    private   static CountDownLatch  countDownLatch ;
    public static int  num  = 0;
    static ExecutorService executorService = Executors.newFixedThreadPool(2);

    static  {
        zkClient = new ZkClient("10.1.15.53:2181");
        ZkClientLock.unlock();
    }


    public static   void lock(){
        try {
            zkClient.createEphemeral(lock);
        }catch (Exception e){
            try {
                System.out.println("重新加锁。。。");
                Thread.sleep(10);
                lock();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }


    }

    public static  void unlock(){
        zkClient.delete(lock);
    }


    public static void main(String[] args) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {

                for (int i  = 0; i < 100000 ; i ++ ){
                    ZkClientLock.lock();
                    num++;
                    System.out.println(Thread.currentThread().getName() + " "  + getStringDateShort() + " " + num);
                    ZkClientLock.unlock();
                }
            }
        });

        executorService.execute(new Runnable() {
            @Override
            public void run() {

                for (int i  = 0; i < 100000 ; i ++ ){
                    ZkClientLock.lock();
                    num++;
                    System.out.println(Thread.currentThread().getName() + " "  + getStringDateShort() + " " + num);
                    ZkClientLock.unlock();
                }
            }
        });




        try {
            executorService.shutdown();
            executorService.awaitTermination(100, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }




    public static String getStringDateShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateString = formatter.format(currentTime);
        return dateString;
    }





}



你可能感兴趣的:(redis)