在项目中进程需要使用锁,比如
1.生成全局唯一id,
2.在公共资源中获取某个资源,比如取票等
下面的案例是有一组服务器ip,配置在数据库中,然后每个线程单独获取一个ip,平均分配 每个服务器调用。
如果发现某个服务器宕机,可以在数据库中停用,然后更新ip列表。
public class UrlServiceImpl implements UrlService{
Logger logger = LoggerFactory.getLogger(getClass());
private static List<String> ipList = ZqfConfigure.AI_INDEX_SERVICE_IP_LIST;
private static int ips = ipList.size();
private static long step = 0L;
private static StampedLock stepLock = new StampedLock();
public void setLockIPList(List<String> ipList) {
long stamp = stepLock.writeLock(); // 写锁
try {
this.ipList = ipList;
this.ips = ipList.size();
step = 0L;
} finally {
stepLock.unlockWrite(stamp);// 释放写锁
}
}
@Override
public String getIP() {
String ip = ips == 1? ipList.get(0) : nextIP();
// logger.debug(" getIP : step = " + step);
return StringUtils.isEmptyWithTrim(ip) ? nextIP() : ip;
}
@Override
public String getDefaultIP() {
return ipList.get(0);
}
@SuppressWarnings("finally")
private String nextIP(){
String ip = null;
long stamp = stepLock.writeLock(); // 写锁
try {
ip = ipList.get((int) (step%ips));
step++;
} finally {
stepLock.unlockWrite(stamp);// 释放写锁
return ip;
}
}
}
public interface UrlService {
public String getIP();
public String getDefaultIP();
}
调用方法
public String getIP(){
UrlService urlService = new UrlServiceImpl();
return urlService.getIP();
}
public String getDefaultIP() {
UrlService urlService = new UrlServiceImpl();
return urlService.getDefaultIP();
}
上面的案例可以均衡动态分配服务器资源,比如某个服务器A有进程8个,B有进程16个
可以在数据库写入1个A,2个B,这样就可以充分利用A和B的资源了
再一个案例就是内存 公共数据读写
public static Map<Integer, Holiday> HolidayMap = new HashMap<Integer, Holiday>();
private final static StampedLock HolidayMapLock = new StampedLock();
public static Map<Integer, Holiday> getHolidayMap() {
return HolidayMap;
}
public static Holiday getHoliday(int date) {
return HolidayBO.HolidayMap.get(date);
}
public static void setHolidayMap(Map<Integer, Holiday> HolidayMap) {
HolidayBO.HolidayMap = HolidayMap;
}
public static void setHolidayMap() {
if(HolidayBO.holidayList != null && !HolidayBO.holidayList.isEmpty()){
Map<Integer, Holiday> holidaysMap = new HashMap<Integer, Holiday>();
for (Holiday holiday : HolidayBO.holidayList) {
holidaysMap.put(holiday.getDate(), holiday);
}
HolidayBO.setLockHolidayMap(holidaysMap);
}
}
public static List<Holiday> getHolidayList() {
return HolidayBO.holidayList;
}
public static void setHolidayList(List<Holiday> holidayList) {
HolidayBO.holidayList = holidayList;
}
public static void setHolidayList() {
HolidayBO.holidayList = getAllSort();
}
public static void updateHolidayMap(Integer data, Holiday Holiday) {
HolidayBO.HolidayMap.put(data, Holiday);
}
public static void updateHolidayMap(Holiday Holiday) {
updateHolidayMap(Holiday.getDate(), Holiday);
}
public static Map<Integer, Holiday> getLockHolidayMap() {
long stamp = HolidayMapLock.tryOptimisticRead();
Map<Integer, Holiday> map = getHolidayMap();
if (!HolidayMapLock.validate(stamp)) {
stamp = HolidayMapLock.readLock(); // 读锁
try {
map = getHolidayMap();
} finally {
HolidayMapLock.unlockRead(stamp);// 释放读锁
}
}
return map;
}
public static Holiday getLockHolidayMap(int date) {
long stamp = HolidayMapLock.tryOptimisticRead();
Holiday Holiday = getHoliday(date);
if (!HolidayMapLock.validate(stamp)) {
stamp = HolidayMapLock.readLock(); // 读锁
try {
Holiday = getHoliday(date);
} finally {
HolidayMapLock.unlockRead(stamp);// 释放读锁
}
}
return Holiday;
}
public static void setLockHolidayMap(Map<Integer, Holiday> HolidayMap) {
long stamp = HolidayMapLock.writeLock(); // 写锁
try {
setHolidayMap(HolidayMap);
} finally {
HolidayMapLock.unlockWrite(stamp);// 释放写锁
}
}
public static void updateLockHolidayMap(Holiday Holiday) {
long stamp = HolidayMapLock.writeLock(); // 写锁
try {
updateHolidayMap(Holiday);
} finally {
HolidayMapLock.unlockWrite(stamp);// 释放写锁
}
}
public static void updateLockHolidayMap(Integer day, Holiday Holiday) {
long stamp = HolidayMapLock.writeLock(); // 写锁
try {
updateHolidayMap(day, Holiday);
} finally {
HolidayMapLock.unlockWrite(stamp);// 释放写锁
}
}
/**
* @return 返回全部日期列表
*/
public static List<Holiday> getAll(){
List<Holiday> list = getHolidayList();
if(list == null || list.isEmpty()){
Map<Integer, Holiday> map = getLockHolidayMap();
if(map != null && !map.isEmpty()){
list = new ArrayList<Holiday>( map.values());
}
}
return list;
}
map加锁后,更新和读取就不会出错。这个在用在秒级的更新和读取上效率很高。比如股票行情数据,每秒几万的数据更新,和多进程查询等。如果是分布式,再配合redis操作效果会更佳。