相关疑难解决方法(0)

793
推荐指数
17
解决办法
30万
查看次数

使用ConcurrentMap双重检查锁定

我有一段代码可以由多个线程执行,需要执行I/O绑定操作,以初始化存储在一个中的共享资源ConcurrentMap.我需要使这段代码线程安全,并避免不必要的调用来初始化共享资源.这是有缺陷的代码:

    private ConcurrentMap<String, Resource> map;

    // .....

    String key = "somekey";
    Resource resource;
    if (map.containsKey(key)) {
        resource = map.get(key);
    } else {
        resource = getResource(key); // I/O-bound, expensive operation
        map.put(key, resource);
    }
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,多个线程可以检查ConcurrentMap并查看资源不存在,并且所有尝试调用getResource()哪个都很昂贵.为了确保共享资源只进行一次初始化,并在资源初始化后使代码有效,我想做这样的事情:

    String key = "somekey";
    Resource resource;
    if (!map.containsKey(key)) {
        synchronized (map) {
            if (!map.containsKey(key)) {
                resource = getResource(key);
                map.put(key, resource);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是双重检查锁定的安全版本吗?在我看来,自从调用检查以来ConcurrentMap,它的行为类似于声明的共享资源,volatile从而防止可能发生的任何"部分初始化"问题.

java concurrency synchronization double-checked-locking

12
推荐指数
1
解决办法
3493
查看次数

Java中线程安全单例的工厂

这是我一直用于工厂的基本模式的示例,它返回一个线程安全的Singleton:

public class UserServiceFactory {

    private volatile static UserService userService;

    private UserServiceFactory() { }

    public static UserService getInstance() {
        if (userService == null) {
            synchronized(UserServiceImpl.class) {            
                if (userService == null) {
                    userService = new UserServiceImpl();
                }        
            }
        }

        return userService;
    }

}
Run Code Online (Sandbox Code Playgroud)

它使用volatile和double check惯用法来确保创建单个实例并在线程中可见.

是否有更简洁和/或更便宜的方式来实现1.6+中的相同目标.

java singleton multithreading factory

10
推荐指数
1
解决办法
8548
查看次数

是否应该同步延迟加载和缓存HashMap中的Object的方法?

该方法应该同步吗?我想我不明白上下文切换是如何(以及何时)发生的,所以我不知道是否有多个线程可以进入我方法中的if块.

public class ServiceLocator {
    private static final Map<Class, Object> applicationServices =
            new HashMap<Class, Object>();

    /**
     * Locates an application scoped service.  The service is lazy loaded and
     * will be cached permanently.
     *
     * @param type The type of service to locate.
     * @return An application scoped service of the specified type.
     */
    @SuppressWarnings({"unchecked"})
    public synchronized static <T> T getApplicationService(Class<T> type) {
        if(!applicationServices.containsKey(type)) {
            // If this method is NOT synchronized, is it possible for more than
            // one …
Run Code Online (Sandbox Code Playgroud)

java multithreading

3
推荐指数
1
解决办法
236
查看次数