Consistent data services

package com.yy.fastcustom.actualupdate;

import java.util.concurrent.BlockingQueue;

/**
 * Created by zzq on 2019/5/16.
 */
public abstract class ActualDataModelOperationHandler<Data> {
    private String readWriteFlag;

    public final String getReadWriteFlag() {
        return readWriteFlag;
    }

    public final void setReadWriteFlag(String readWriteFlag) {
        this.readWriteFlag = readWriteFlag;
    }

    private long readWaitMillis;

    public final long getReadWaitMillis() {
        return readWaitMillis;
    }

    public final void setReadWaitMillis(long readWaitMillis) {
        this.readWaitMillis = readWaitMillis;
    }

    /**
     * Update the cache information
     *
     * @Return successful return to true
      * / 
    public  abstract  boolean removeCache ();

    /**
     * Updated data
     *
     * @Return successful return to true
      * / 
    public  abstract  boolean updateOriginalDataAndCache ();

    /**
     * Comprehensive read data (existing cache read, can not read reading database)
     *
     * @return
     */
    public abstract Data getOriginalData();

    public  abstract Date getCacheData ();

    public  abstract  void setCacheData (Date date);

    public final void updateData() throws Exception {
        BlockingQueue<ActualDataModelOperationHandler> actualDataModels = ActualDataServiceManager.getUpdateQueue(this.getReadWriteFlag());
        actualDataModels.put(this);
    }

    public final Data readData() {
        In Flag String = the this .getReadWriteFlag ();
         IF (ActualDataServiceManager.contains (In Flag)) {
             Long the startTime = System.currentTimeMillis (); // current number of milliseconds 
            for (; to true ;) {
                 IF (ActualDataServiceManager.noContains (In Flag) || (System.currentTimeMillis () - the startTime> the this .getReadWaitMillis ())) // If the spin time is greater than the set threshold 
                    BREAK ;
                Data retData = this.getCacheData();
                if (retData != null)
                    return retData;
            }
        }
        Data retData = this.getCacheData();
        if (retData != null)
            return retData;
        retData = this.getOriginalData();
        if (retData != null)
            this.setCacheData(retData);
        return retData;
    }
}
package com.yy.fastcustom.actualupdate;

import java.util. * ;
import java.util.concurrent. * ;

/**
 * Created by zzq on 2019/5/16.
 */
public class ActualDataServiceManager {
    private static volatile List<DataUpdateQueueWrapper> queueList = null;
    private static Map<String, Object> updateOperationTag = null;
    private static ExecutorService executor = null;

    public static void initQueueNum(int size) {
        if (queueList == null)
            synchronized (ActualDataServiceManager.class) {
                if (queueList == null)
                    initBasicObject(size);
            }
    }

    private static void initBasicObject(int size) {
        int sizeExtend = size * 1000;//hash范围放大1000倍
        queueList = new ArrayList<>(sizeExtend);
        updateOperationTag = new ConcurrentHashMap<>();
        executor = new ThreadPoolExecutor(
                size,
                size,
                60L,
                TimeUnit.SECONDS,
                new SynchronousQueue(),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        DataUpdateQueueWrapper ary[] = new DataUpdateQueueWrapper[size];
        for (int i = 0; i < size; i++) {
            DataUpdateQueueWrapper dataUpdateQueueWrapper = new DataUpdateQueueWrapper();
            ary[i] = dataUpdateQueueWrapper;
            executor.submit(dataUpdateQueueWrapper);
        }
        for ( int I = 0; I <sizeExtend; I ++) { // generate a virtual node hash 
            queueList.add (ary [I% size]);
        }
    }

    /**
     The mark * Get Queue
     *
     * @param flag
     * @Return 
     * / 
    public  static BlockingQueue <ActualDataModelOperationHandler> getUpdateQueue (String In Flag) throws Exception {
         IF (queueList == null ) {
             the throw  new new Exception ( "before calling this method, the number of calls initQueueNum update the queue initialization" );
        }
        int hash;
        int index = flag == null ? 0 : (hash = flag.hashCode()) ^ (hash >>> 16);
        return queueList.get((queueList.size() - 1) & index).getQueue();
    }

    public static void addFlag(String flag) {
        updateOperationTag.put(flag, "flagValue");
    }

    public static void removeFlag(String flag) {
        updateOperationTag.remove(flag);
    }

    public static boolean contains(String flag) {
        return updateOperationTag.containsKey(flag);
    }

    public static boolean noContains(String flag) {
        return !contains(flag);
    }
}
package com.yy.fastcustom.actualupdate;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Created by zzq on 2019/5/16.
 */
public class DataUpdateQueueWrapper implements Callable {
    private volatile BlockingQueue<ActualDataModelOperationHandler> updateQueue = null;

    {
        updateQueue = new LinkedBlockingQueue<>();
    }

    public BlockingQueue<ActualDataModelOperationHandler> getQueue() {
        return updateQueue;
    }

    @Override
    public Object call() throws Exception {
        for (; true; ) {
            ActualDataModelOperationHandler actualDataModel = updateQueue.take();
            String flag = actualDataModel.getReadWriteFlag();
            ActualDataServiceManager.addFlag (In Flag); // here by a separate worker thread loop queue 
            the try {
                 Boolean B1 = actualDataModel.removeCache ();
                 IF (B1) // If the cache deletion fails, and no update is flushed to the database cache; buffer deleted successfully even if updateDbAndCache failed also to ensure the consistency of old data 
                    actualDataModel.updateOriginalDataAndCache ();
            } finally {
                ActualDataServiceManager.removeFlag(flag);
            }
        }
    }
}
package com.yy.fastcustom.actualupdate;


/**
 * Created by zzq on 2019/5/27/027.
 */
public class TestDataModel extends ActualDataModelOperationHandler<String> {
    public static void main(String[] args) {
//        ceshi_hash();


        String key = "1";
        ActualDataServiceManager.initQueueNum(3);

        final TestDataModel actualDataModel = new TestDataModel();
        actualDataModel.setReadWriteFlag(key);
        actualDataModel.setReadWaitMillis ( 20 * 1000 );

        try {
            actualDataModel.updateData();
        } catch (Exception e) {
            e.printStackTrace ();
        }

        new Thread(() -> {
            String ret = null ;
            ret = actualDataModel.readData();

            System.out.println("=====end out====" + ret);
        }).start();
    }

    private static void ceshi_hash() {
        int p1 = 356349;
        int p2 = 453546;
        int p3 = 678345;
        int p4 = 768678;
        int p5 = 967897;

        int r1 = p1 & 2;
        int r2 = p2 & 2;
        int r3 = p3 & 2;
        int r4 = p4 & 2;
        int r5 = p5 & 2;

        int r1_ = p1 & 2999;
        int r2_ = p2 & 2999;
        int r3_ = p3 & 2999;
        int r4_ = p4 & 2999;
        int r5_ = p5 & 2999;

        System.out.println("====");
    }

    volatile String uu = null;

    @Override
    public boolean removeCache() {
        for (int i = 0; i < 5; i++) {
            System.out.println("====removeCache==缓存==");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
        }
        return true;
    }

    @Override
    public boolean updateOriginalDataAndCache() {
        for (int i = 0; i < 5; i++) {
            System.out.println ( "Database == ==== updateOriginalDataAndCache ==" );
             the try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
            if (i == 1) {
                Uu = "acquires the cache data" ;
            }
        }
        return false;
    }

    @Override
    public void setCacheData(String s) {
        u = s;
        System.out.println ( "==== read the database is successful, put it in the cache ==" );
    }

    @Override
    public String getOriginalData () {
         return "not found the cache, loaded from the database!" ;
    }

    @Override
    public String getCacheData() {
        System.out.println ( "==== read cache but did not read ==" );
         return  null ;
    }
}

 

Guess you like

Origin www.cnblogs.com/zzq-include/p/11019927.html