`

并发集合类ConcurrentSkipListSet

 
阅读更多

ConcurrentSkipListSet

ConcurrentSkipListSet(在JavaSE 6新增的)提供的功能类似于TreeSet,能够并发的访问有序的set。因为ConcurrentSkipListSet是基于“跳跃列表(skip list)”实现的,只要多个线程没有同时修改集合的同一个部分,那么在正常读、写集合的操作中不会出现竞争现象。

有一个业务需求,需要对用户进行增删查改的操作。

当用户第一次查询时会把所以的数据都从数据库当中查询出来。放入cache当中。

如果有增加时,会把这个新用用户放入并行集合类ConcurrentSkipListSet 当中。

删除时,数据库删除后会把这个用户信息从ConcurrentSkipListSet 中删除。

修改时。会从ConcurrentSkipListSet 中根据ID找到这个数据。然后删除。然后ADD进去。

/**

 *

 * @author matt.yan

 */

package uma.admin.cache;


import java.util.Arrays;

import java.util.Comparator;

import java.util.Iterator;

import java.util.List;

import java.util.concurrent.ConcurrentSkipListSet;

import java.util.regex.Pattern;

import uma.admin.ws.User;

import uma.admin.ws.UserAccount;

import uma.ws.model.SourceModel.Source;

import uma.ws.model.UserAccountModel;

import uma.ws.model.UserAccountModelList;

import uma.ws.model.UserModel;

import uma.ws.model.UserModelList;


public class UserCache  {

    private static final UserCache usersCache = new UserCache();

    private static volatile ConcurrentSkipListSet<UserModel> models = null; 

    

    public static UserCache getUsersCache() throws Exception {  

        if (models == null) {

            synchronized (UserCache.class) {

                if (models == null) {

                   UserModelList list = User.usersGet(); 

                   models = new ConcurrentSkipListSet<UserModel> (

                                new Comparator<UserModel>() {

                                    @Override

                                    public int compare(UserModel o1, UserModel o2) { 

                                       if(o1.getLastName() == null && o1.getFirstName() == null) {

                                           return -1;

                                       }

                                       if(o2.getLastName() == null && o2.getFirstName() == null) {

                                           return 1;

                                       }

                                       if(o1.getLastName() == null || o2.getLastName() == null) {

                                           return o1.getLastName() == null ? -1 : 1;

                                       }

                                       

                                       int compare = o1.getLastName().trim().toUpperCase().compareTo(o2.getLastName().trim().toUpperCase());

                                       if(compare == 0){

                                           if(o1.getFirstName() == null || o1.getFirstName() == null){

                                               return o1.getLastName() == null ? -1 : 1;

                                           }

                                           compare = o1.getFirstName().trim().toUpperCase().compareTo(o2.getFirstName().trim().toUpperCase());

                                       }

                                       return compare;

                                    }

                                });

                   for(UserModel userModel : list){

                       models.add(userModel);

                   }

                }

            }

        } 

        return usersCache;    

    }

    

   

    public List getModels(String search, long searchRoleId, int searchStatusId) throws Exception {        

        ConcurrentSkipListSet<UserModel> localSet = models;

        if (localSet == null) {

            return null;

        }

        if ((search == null || search.isEmpty()) && searchRoleId < 0 && searchStatusId < 0) {

            return Arrays.asList(localSet.toArray());                        

        }        

        

        List list = new UserModelList();

        Iterator it = localSet.iterator();

        if (search == null || search.isEmpty()) {

            while (it.hasNext()) {

                UserModel user = (UserModel) it.next();

                if ((user.getRoleId() == searchRoleId || searchRoleId < 0) &&

                    (user.getStatus() == searchStatusId || searchStatusId < 0)) {

                        list.add(user);

                }

            }

             

        }

        else {

            search = search.toLowerCase().trim();

            Pattern integerPattern = Pattern.compile("^\\d*$");

            //integer will search pams id

            UserAccountModelList userAccounts = null;

            if (integerPattern.matcher(search).matches()) {

                userAccounts = UserAccount.getUserAccountsByReference(Source.PAMS.toString(), search);

            }

 

            while (it.hasNext()) {

                UserModel user = (UserModel) it.next();

                //normally this list will be no more than 10 records 

                if(userAccounts != null) {

                    for(UserAccountModel userAccount : userAccounts){

                        if((userAccount.getUserId() == user.getId())

                           && (user.getRoleId() == searchRoleId || searchRoleId < 0) &&

                            (user.getStatus() == searchStatusId || searchStatusId < 0)){

                            list.add(user);

                            continue;

                        }

                    }

                }

                String userId =  new Long(user.getId()).toString();

                if (((userId != null && userId.contains(search)) ||                    

                        (user.getEmail() != null && user.getEmail().toLowerCase().contains(search)) ||

                        (user.getFirstName() != null && user.getFirstName().toLowerCase().contains(search)) ||

                        (user.getLastName() != null && user.getLastName().toLowerCase().contains(search)) ||

                        (user.getLoginName() != null && user.getLoginName().toLowerCase().contains(search))

                     ) 

                     && (user.getRoleId() == searchRoleId || searchRoleId < 0) &&

                        (user.getStatus() == searchStatusId || searchStatusId < 0)) 

                {

                        list.add(user);

                }

            }

        }

        return list;

    }

    

    /*

     * this operation will not be heavily used

     */

    public UserModel addModel(UserModel user) throws Exception {        

        if(user == null){

            return null;

        }

        user = User.userCreate(user);

        if(user != null){

            ConcurrentSkipListSet<UserModel> localSet = models;

            localSet.add(user);

        }

        return user;

    }

    

    /*

     * this operation will not be heavily used

     */

    public UserModel updateModel(UserModel user) throws Exception {        

        if(user == null){

            return null;

        }

        user = User.userUpdate(user);

        put(user);

        return user;

    }

    

    /*

     * Password format:

     * [aaabbbn] where:

     * aaa = first three characters of client’s first name and

     * bbbb = first three characters of client’s surname, and

     * n = suffix number – this is only required where the ‘a’ and ‘b’ combination already exists. Starting at 1, continue until a unique combination is found.

     * This function is only used in creating a user

     */

    public String getLoginName(String firstName, String lastName) {

        if(firstName == null || lastName == null

           || firstName.isEmpty() || lastName.isEmpty()) {

            return null;

        }

        if (firstName.length()>3) {

            firstName = firstName.substring(0, 3);

        }

        if (lastName.length()>3) {

            lastName = lastName.substring(0, 3);

        }

        firstName = firstName.toLowerCase();

        lastName = lastName.toLowerCase();

        String loginName = firstName + lastName;

        int length = loginName.length();

        for(int i = length; i<6 ; i++) {

            loginName = loginName + "1";

        }

        ConcurrentSkipListSet<UserModel> localSet = models;

        int largestId =0;

        String matchReg = "^" + loginName + "[0-9]*";

        for(UserModel user : localSet) {

            if(user.getLoginName() != null && user.getLoginName().toLowerCase().matches(matchReg)) {

                int i = Integer.parseInt(user.getLoginName().substring(6));

                if (largestId < i) {

                    largestId = i;

                }

            }

        }

        largestId++;

        return loginName + largestId;        

    }

    /*

     * this operation will not be heavily used

     */

    private void put(UserModel wsUser) {

        ConcurrentSkipListSet<UserModel> localSet = models;

        if(wsUser == null || localSet == null){

            return;

        }

        UserModel cacheUser = null;

        for(UserModel user : localSet){

            if(user.getId() == wsUser.getId()) {

                cacheUser = user;

                break;

            }

        }

 

        synchronized (UserCache.class) {

            if(cacheUser != null){

                localSet.remove(cacheUser);

            }

            localSet.add(wsUser);

        }

    }

    

    /*

     * this operation will not be heavily used

     */

    public UserModel getUserById(long id) throws Exception {

        UserModel wsUser = User.userGet(id);

        put(wsUser);

        return wsUser;

    }


}

    

    

分享到:
评论

相关推荐

    java集合-ConcurrentSkipListSet的使用

    ConcurrentSkipListSet 是Java中的一个线程安全的有序集合类,它基于跳表(Skip List)数据结构实现。 下面是关于 ConcurrentSkipListSet 的一些重要信息: 线程安全性:ConcurrentSkipListSet 是线程安全的,可以...

    Java concurrency集合之ConcurrentSkipListSet_动力节点Java学院整理

    ConcurrentSkipListSet是Java concurrency集合中的一种线程安全的有序集合,适用于高并发的场景。与TreeSet不同,ConcurrentSkipListSet是线程安全的,同时它也实现了NavigableSet接口,提供了更多的操作方法。 ...

    concurrent-1.3.4.jar

    concurrent-1.3.4 使用concurrent包可以实现以下功能: ...并发集合类:concurrent包提供了一些并发集合类,如ConcurrentHashMap、ConcurrentSkipListSet等,可以在多线程环境下安全地对集合进行操作,支持高并发访问。

    Java常见的线程安全的类.docx

    线程安全的实现方式多种多样,包括使用synchronized关键字、原子类、阻塞队列以及特定的并发集合类等。下面将详细讨论这些线程安全的Java类及其工作原理。 1. synchronized关键字:Java中的synchronized关键字可以...

    JAVA并发容器代码随读1

    - CopyOnWriteArraySet 和 CopyOnWriteArrayList 类似,它们使用“写时复制”策略,当需要修改集合时,会创建一个新的底层数组并复制原数组的内容,这样在并发读取时不会被打断,提高了并发性能。 总结来说,Java...

    Java并发编程与高并发解决方案之并发容器(J.U.C).docx

    在Java中,为了提供高性能、低延迟的并发数据结构,Java提供了多种并发容器类,这些类主要位于`java.util.concurrent`包内,通常被称为J.U.C(Java Util Concurrency)容器。 ##### 1. CopyOnWriteArrayList `...

    java 并发编程

    使用ThreadLocal保存状态变量,控制变量的可见性(通过volatile关键字或原子变量如AtomicLong和AtomicReference等),在访问共享状态变量时使用同步机制,以及使用Java并发库提供的并发集合和原子操作。 监视器锁...

    Java基础学习25.pdf

    7. **并发集合类**:在多线程环境中,为了保证线程安全,Java提供了专门的线程安全集合类: - CopyOnWriteArrayList:线程安全的ArrayList实现,在写操作时复制底层数组。 - ConcurrentHashMap:线程安全的HashMap...

    Java concurrency之集合_动力节点Java学院整理

    在多线程场景下,Java并发包`java.util.concurrent`(简称JUC)提供了线程安全的并发集合类。比如: 1. `CopyOnWriteArrayList` 是线程安全的`ArrayList`替代品,通过写时复制(Copy-On-Write)策略保证并发安全,...

    集合效率不完全皮恩车

    通过对数组`chars`进行1000000万次操作,我们可以评估各种集合类在插入、哈希计算、散列、批量操作、删除、大小查询、位置查找、迭代和存在性检查等方面的性能。 首先,我们来看List接口的实现: 1. **ArrayList**...

    Java——JUC

    - `ConcurrentSkipListMap`和`ConcurrentSkipListSet`:跳表实现的并发集合,支持高效并发的查找、插入和删除操作。 4. **原子类(Atomic Classes)** - `AtomicInteger`、`AtomicLong`等原子类提供了一种在不...

    aduna-commons-concurrent-2.5.0.jar.zip

    3. **并发容器**:库中包含了一些增强版的集合类,如并发队列、并发哈希映射等,它们在多线程环境下表现出更好的性能和线程安全性,避免了竞态条件和死锁的问题。 4. **工具类**:Aduna Commons Concurrent还提供了...

    java中集合排序

    集合框架是Java中处理集合类的一个核心部分,它提供了一种高效、灵活的方式来组织和操作数据。本文将深入探讨Java中集合排序的相关知识点,包括基本概念、排序方法以及常用类的实现。 1. **集合接口与实现** Java...

    66丨迭代器模式(中):遍历集合的同时,为什么不能增删集合元素?1

    此外,有些集合类如`CopyOnWriteArrayList`和`ConcurrentSkipListSet`提供了线程安全的迭代器,它们允许在遍历过程中进行并发的修改,但代价是性能上的损失,因为它们会在修改时创建集合的副本。 总的来说,迭代器...

    Iterator的使用

    3. **并发迭代器**:在多线程环境下,Java的`ConcurrentSkipListSet`和`ConcurrentLinkedQueue`等并发集合类提供了`iterator()`方法,返回的迭代器能够安全地在并发环境中使用。 总之,迭代器是访问聚合对象的常用...

    jdk1.5中文帮助文档

    对集合框架进行了优化,如`List`、`Set`和`Map`接口新增了更多的操作方法,如`removeIf()`、`replaceAll()`等,同时引入了`TreeSet`和`TreeMap`的并发版本`ConcurrentSkipListSet`和`ConcurrentSkipListMap`。...

    20个最佳的Java集合框架面试题目.zip

    19. **并发容器**:除了ConcurrentHashMap,还有ConcurrentLinkedQueue、ConcurrentSkipListMap和ConcurrentSkipListSet等并发容器,适用于高并发场景。 20. **集合与数组的转换**:toArray()方法可以将集合转换...

    jdk1.8 api 中文文档

    另外,还引入了新的并发集合类,如ConcurrentSkipListMap和ConcurrentSkipListSet。 7. **Method Handles和InvokeDynamic**:这两个特性增强了动态类型的能力,提高了反射和代码生成的效率。 8. **Optional类**:...

    多线程编程.docx

    并发容器是Java并发编程中的重要组成部分,它们提供了比传统集合类更强大的线程安全性。以下是一些关键的并发容器类型及其特点: - **队列** - **阻塞队列**:是一种特殊的队列,当队列为空时,从队列中获取元素的...

    [线程技术]排序对象

    需要注意的是,虽然这个例子中使用了线程安全的 `List`,但在实际应用中,如果多线程环境中的排序操作是独立的,可以考虑使用并发集合,如 `ConcurrentSkipListSet` 或 `ConcurrentLinkedQueue`,它们在性能上可能更...

Global site tag (gtag.js) - Google Analytics