相关疑难解决方法(0)

Java中的最终静态变量是否安全?

我已经阅读了很多,但没有找到明确的答案.

我有一个看起来像这样的课程:

    public class Foo() {

        private static final HashMap<String, HashMap> sharedData;

        private final HashMap myRefOfInnerHashMap;

        static {
           // time-consuming initialization of sharedData
           final HashMap<String, String> innerMap = new HashMap<String, String>;
           innerMap.put...
           innerMap.put...
           ...a

           sharedData.put(someKey, java.util.Collections.unmodifiableMap(innerMap));
        }

        public Foo(String key) {
            this.myRefOfInnerHashMap = sharedData.get(key);
        }

        public void doSomethingUseful() {
            // iterate over copy
            for (Map.Entry<String, String> entry : this.myRefOfInnerHashMap.entrySet()) {
                ...
            }
        }
     }
Run Code Online (Sandbox Code Playgroud)

我想知道从Foo实例访问sharedData是否是线程安全的(如构造函数和doSomethingUseful()中所示).Foo的许多实例将在多线程环境中创建.

我的意图是sharedData在静态初始化程序中初始化,之后不再修改(只读).

我读过的是不可变对象本质上是线程安全的.但我只是在实例变量的上下文中看到了这一点.不可变的静态变量是否安全?

我找到的另一个构造是ConcurrentHashMap.我可以创建ConcurrentHashMap类型的sharedData但是它包含的HashMaps也必须是ConcurrentHashMap类型的?基本上..

private static final ConcurrentHashMap<String, HashMap> sharedData;
Run Code Online (Sandbox Code Playgroud)

要么

private static final ConcurrentHashMap<String, ConcurrentHashMap> …
Run Code Online (Sandbox Code Playgroud)

java static multithreading final hashmap

26
推荐指数
5
解决办法
3万
查看次数

在Java中,如果它是只读的,我是否需要声明我的集合是否已同步?

我的J2EE webapp启动时,我一次填充一个集合.然后,几个线程可以同时访问它,但只能读取它.

我知道使用同步集合对于并行写入是强制性的,但是我仍然需要它来进行并行读取吗?

java multithreading synchronization web-applications

19
推荐指数
3
解决办法
4836
查看次数

在Java中,同时更改对HashMap读取的引用是安全的

我希望这不是一个愚蠢的问题......

我的代码中的代码类似于以下代码:

public class ConfigStore {

    public static class Config {

        public final String setting1;
        public final String setting2;
        public final String setting3;

        public Config(String setting1, String setting2, String setting3) {
            this.setting1 = setting1;
            this.setting2 = setting2;
            this.setting3 = setting3;
        }

    }

    private volatile HashMap<String, Config> store = new HashMap<String, Config>();

    public void swapConfigs(HashMap<String, Config> newConfigs) {
        this.store = newConfigs;
    }

    public Config getConfig(String name) {
        return this.store.get(name);
    }

}
Run Code Online (Sandbox Code Playgroud)

处理请求时,每个线程将使用getConfig()函数从存储中请求使用配置.但是,定期(最有可能每隔几天),使用swapConfigs()函数更新和交换配置.调用swapConfigs()的代码不会保留对它传入的Map的引用,因为它只是解析配置文件的结果.

  • 在这种情况下,volatile商店实例变量仍然需要关键字吗?
  • volatile关键字带来任何潜在的性能瓶颈,我应该知道的或可避免因为读取的速度大大超过写入的速度?

非常感谢,

java concurrency multithreading volatile

14
推荐指数
3
解决办法
4193
查看次数

在自己的构造函数中调用thread.start()

一个线程在它自己的构造函数中调用this.start()是否合法?如果是这样,这会导致什么样的潜在问题?我知道对象不会完全初始化,直到构造函数运行完成,但除此之外还有其他问题吗?

java multithreading

10
推荐指数
2
解决办法
2万
查看次数

java map并发更新

我正在尝试创建一个Map带有int值并通过多个线程增加它们.两个或多个线程可能会增加相同的密钥.

ConcurrentHashMap 文档对我来说非常不清楚,因为它表明:

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove)

我想知道以下代码使用ConcurrentHashMap是否正常:

myMap.put(X, myMap.get(X) + 1);

如果没有,我该怎么办呢?

java concurrency map

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

设置HashMap线程安全吗?

HashMap我的程序中有一个由多个线程访问,偶尔由一个线程设置.

例如:

Map<String, String> myMap = new HashMap<String, String>();
Run Code Online (Sandbox Code Playgroud)

这可以通过多个线程访问.每小时一次,一个线程调用:

myMap = myRefreshedVersionOfTheMap;
Run Code Online (Sandbox Code Playgroud)

所以我的问题是这是否是线程安全的.如果两个映射始终都有密钥"importantKey",那么读取线程是否可以在"importantKey"不存在时访问映射?

编辑:

感谢答案,我意识到这个问题实际上是独立的HashMap.这是一个关于对象引用分配的问题.

java multithreading reference thread-safety java-memory-model

10
推荐指数
2
解决办法
5025
查看次数

安全出版没有发生 - 之前?无论如何除了最后?

根据JCP(16.2.2.安全出版物):

这种情况发生之前 - 保证实际上是一种比安全出版物更强的可见性和排序承诺.当X安全地从A发布到B时,安全发布保证了X的状态的可见性,但不保证A可能触及的其他变量的状态.但是如果A在队列中放置X,那么在B从该队列中取出X之前,不仅B在A离开它的状态下看到X(假设X后来没有被A或其他任何人修改过),但B看到A在切换之前所做的一切(再次,同样需要注意)

我想知道什么时候安全发布可以没有发生 - 也就是说没有使用volatile/atomics或同步(或通过使用任何内部列出的AQS之类的框架)?

一种情况是不可变对象中的最终字段,您可以将其发布为没有任何其他步骤.

还有其他案件吗?

UPD:重新阅读3.5.3.安全发布惯用语,另一种情况 - "从静态初始化程序初始化对象引用".现在看来这些都是选择.

java concurrency multithreading visibility

6
推荐指数
1
解决办法
813
查看次数

这类Threadsafe?


下面的课程线程安全吗?

class ImmutablePossiblyThreadsafeClass<K, V> {

    private final Map<K, V> map;

    public ImmutablePossiblyThreadsafeClass(final Map<K, V> map) {
        this.map = new HashMap<K, V>();

        for (Entry<K, V> entry : map.entrySet()) {
            this.map.put(entry.getKey(), entry.getValue());
        }
    }

    public V get(K key) {
        return this.map.get(key);
    }
}
Run Code Online (Sandbox Code Playgroud)

java concurrency immutability thread-safety

2
推荐指数
1
解决办法
527
查看次数