单例模式应用【创建模式第八篇】
预定式存储:
为了保证在任何情况下键值都不会出现重复,应当使用预定式键值存储办法。在请求一个键值时,首先将数据库中的键值更新为下一个可用值,
然后将旧值提供给客户端。这样万一出现运行中断的话,最多就是这个键值被浪费掉。
记录式存储:
键值首先被返还给客户端,然后记录到数据库中。这样做的缺点是,一旦系统中断,就有可能出现客户端已经使用了一个键值,而这个键值却
没有来得及存储到数据库中的情况。在系统重启后,系统还会从这个已经被使用过的键值开始,从而导致错误。
单例模式应用:序列键管理器
方案一:没有数据库的情况 //序列键生成器(单例类) public class KeyGenerator{ private static KeyGenerator keygen = new KeyGenerator(); private int key = 1000; private KeyGenerator(){} //静态工厂方法,提供自己的实例 public static KeyGenerator getInstance(){ return keygen; } //取值方法,提供一个合适的键值 public synchronized int getNextKey(){ return key ++; } } //客户端 public class Client{ private static KeyGenerator keygen; public static void main(String args[]){ keygen = KeyGenerator.getInstance(); System.out.println("Key = " + keygen.getNextKey()); System.out.println("Key = " + keygen.getNextKey()); System.out.println("Key = " + keygen.getNextKey()); } } //当系统重启时,计数就要重新开始 方案二:有数据库的情况: //序列键生成器(单例类) public class KeyGenerator{ private static KeyGenerator keygen = new KeyGenerator(); private int key = 1000; private KeyGenerator(){} //静态工厂方法,提供自己的实例 public static KeyGenerator getInstance(){ return keygen; } //取值方法,提供一个合适的键值 public synchronized int getNextKey(){ return getNextKeyFromDB(); } private int getNextKeyFromDB(){ String sql1 = "UPDATE KeyTable SET keyValue = keyValue + 1"; String sql2 = "SELECT keyValue FROM KeyTable"; //execute the update SQL //run the select query //示意性的返还一个数值 return 1000; } } //每次都向数据库查询键值,将这个键值登记到表里,然后将查询结果返还给客户端 方案三:键值的缓存方案 //序列键生成器(单例类) public class KeyGenerator{ private static KeyGenerator keygen = new KeyGenerator(); private static final int POOL_SIZE = 20; //用于缓存20条记录 private KeyInfo key; private KeyGenerator(){ key = new KeyInfo(POOL_SIZE); } //静态工厂方法,提供自己的实例 public static KeyGenerator getInstance(){ return keygen; } //取值方法,提供一个合适的键值 public synchronized int getNextKey(){ return key.getNextKey(); } } //KeyInfo类 public class KeyInfo{ private int keyMax; private int keyMin; private int nextKey; private int poolSize; public KeyInfo(int poolSize){ this.poolSize = poolSize; retrieveFromDB(); //retrieve(检索) } //取值方法,提供键的最大值 public int getKeyMax(){ return keyMax; } public int getKeyMin(){ return keyMin; } //取值方法,提供键的当前值 public int getNextKey(){ if(nextKey > keyMax){ retrieveFromDB(); } return nextKey ++; } //内部方法,从数据库提取键的当前值 private void retrieveFromDB(){ String sql1 = "UPDATE KeyTable SET keyValue = keyValue +" + poolSize + "WHERE keyName = 'PO_NUMBER'"; String sql2 = "SELECT keyValue FROM KeyTable WHERE keyName = 'PO_NUMBER'"; //execute the above queries in a transaction and commit it //commit提交/委托 //assume the value returned is 1000 //assume假设 int keyFromDB = 1000; keyMax = keyFromDB; keyMin = keyFromDB - poolSize + 1; nextKey = keyMin; } } //客户端 public class Client{ private static KeyGenerator keygen; public static void main(String args[]){ keygen = KeyGenerator.getInstance(); for(int i = 0; i < 20; i ++){ System.out.println("Key(" + (i+1) + ")=" + keygen.getNextKey()); } } } 方案四:有缓存的多序列键生成器 //KeyGenerator import java.util.HashMap; public class KeyGenerator{ private static KeyGenerator keygen = new KeyGenerator(); private static final int POOL_SIZE = 20; private HashMap keyList = new HashMap(10); private KeyGenerator(){ } public static KeyGenerator getInstance(){ return keygen; } public synchronized int getNextKey(String keyName){ KeyInfo keyInfo; if(keyList.containsKey(keyName)){ keyInfo = (KeyInfo)keyList.get(keyName); System.out.println("Key found"); }else{ keyInfo = new KeyInfo(POOL_SIZE,keyName); keyList.put(keyName,keyInfo); System.out.println("New key created"); } return keyInfo.getNextKey(keyName); } } //KeyInfo类 public class KeyInfo{ private int keyMax; private int keyMin; private int nextKey; private int poolSize; private String keyName; public KeyInfo(int poolSize,String keyName){ this.poolSize = poolSize; this.keyName = keyName; retrieveFromDB(); //retrieve(检索) } //取值方法,提供键的最大值 public int getKeyMax(){ return keyMax; } public int getKeyMin(){ return keyMin; } //取值方法,提供键的当前值 public int getNextKey(){ if(nextKey > keyMax){ retrieveFromDB(); } return nextKey ++; } //内部方法,从数据库提取键的当前值 private void retrieveFromDB(){ String sql1 = "UPDATE KeyTable SET keyValue = keyValue +" + poolSize + "WHERE keyName = " + keyName + ""; String sql2 = "SELECT keyValue FROM KeyTable WHERE keyName = " + keyNAme + ""; //execute the above queries in a transaction and commit it //commit提交/委托 //assume the value returned is 1000 //assume假设 int keyFromDB = 1000; keyMax = keyFromDB; keyMin = keyFromDB - poolSize + 1; nextKey = keyMin; } } //客户端 public class Client{ private static KeyGenerator keygen; public static void main(String args[]){ keygen = KeyGenerator.getInstance(); for(int i = 0; i < 20; i ++){ System.out.println("Key(" + (i+1) + ")=" + keygen.getNextKey("PO_NUMBER")); } } }273P 方案五:多例模式 //KeyGennerator import java.util.HashMap; public class KeyGenerator{ private static HashMap Kengens = new HashMap(10); private static final int POOL_SIZE = 20; private KeyInfo keyinfo; private KeyGenerator(){} private KeyGenerator(String keyName){ keyinfo = new KeyInfo(POOL_SIZE,keyName); } public static synchronized KeyGenerator getInstance(String keyName){ KeyGenerator keygen; if(kengens.containsKey(keyName)){ keygen = (KeyGenerator)kengens.get(keyName); }else{ keygen = new KeyGenerator(keyName); } return keygen; } public synchronized int getNextKey(){ return keyinfo.getNextKey(); } //KeyInfo类与方案四里的相同 } //客户端 public class Client{ private static KeyGenerator keygen; public static void main(String args[]){ keygen = KeyGenerator.getInstance("PO_NUMBER"); for(int i = 0; i < 20; i ++){ System.out.println("Key(" + (i+1) + ")=" + keygen.getNextKey()); } } }
相关推荐
fraternityjava 2020-06-14
Kele0 2020-05-30
ahnuzfm 2020-05-07
gongruitao 2020-05-02
elizabethxxy 2020-04-27
xiaoemo0 2020-04-08
付春杰Blog 2020-03-26
JF0 2020-03-20
ahnuzfm 2020-02-03
Ingram 2020-01-16
缘起宇轩阁 2019-12-30
gongruitao 2020-01-04
zuixin 2020-01-03
pengkunstone 2019-12-27
waitui00 2019-12-22