首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java安全多线程

Java安全多线程
EN

Stack Overflow用户
提问于 2020-03-20 18:17:18
回答 2查看 41关注 0票数 0

我有几个关于多线程的问题(我想安全快速地完成我的小项目)。

我有一个类库。我会将用户请求添加到一个文件中。

代码语言:javascript
复制
public static volatile HashMap<String, GooglePlayGame> games = new HashMap<>(500);

在每次应用启动时,我都会在静态块中使用一个文件(json+Jackson)来初始化这个哈希图:

代码语言:javascript
复制
static {
    TypeFactory typeFactory = mapper.getTypeFactory();
    MapType mapType = typeFactory.constructMapType(HashMap.class, String.class, GooglePlayGame.class);
      try {
          games = mapper.readValue(new File("games.json"), mapType);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

每个用户的请求(使用特殊命令/library)将被处理,然后新的“键-值”对将被添加到全局哈希图中,当然,如果键不存在(用containsKey检查)。然后使用这个hashmap (而不是从文件)。

然后我想把新的配对写入我的文件中。为此,我想创建一个新线程,如下所示:

代码语言:javascript
复制
Thread thread = new Thread(() -> {
            try {
                mapper.writeValue(new File("games.json"), games);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        thread.start();

问题:

1)“易失性”有帮助吗?它是否保证在写入文件时,我将始终看到所有最后添加的对?

2)如果..不是每对新的写入文件,而是每10对写入文件?该怎么做呢?使用CountDownLatch?如果是,如何正确组织这一点?我不太擅长多线程。但是如果程序崩溃了,我收到了9个新的请求,这些请求对就会丢失!

3)顺便问一下,我是在这里创建一个新文件,还是只是覆盖旧文件?如果我总是创建新文件,这就有点糟糕了。杰克逊在创建新文件还是覆盖旧文件?

EN

回答 2

Stack Overflow用户

发布于 2020-03-20 18:40:20

1)在这种情况下,volatile关键字不会给你想要的东西。当你搜索它所做的事情时,它可能会有一点误导。你可以发现"volatile关键字保证了对变量的所有写操作对所有线程都是可见的“。它的意思是,当你给变量分配一个新的值(新对象)时,它将是可见的。但是,如果更改了分配给该变量的对象,则这些更改不一定对所有线程都可见。

在本例中,您修改的是Hashmap,而不是变量,因此它可能不可见。您应该考虑使用一些线程安全的专用内置集合,如ConcurrentHashMap

2)你不能确保所有的数据都会在崩溃的情况下写入文件。在每次输入之后写入数据总是更安全的,但这取决于它发生的频率。如果是一分钟一次,那么一次写1也没问题,如果是每秒几千次,那么你应该考虑批量写入。

3)我认为自己测试它应该很容易。此外,它与主要问题并不相关,主要问题是关于多线程的。

票数 1
EN

Stack Overflow用户

发布于 2020-03-20 20:49:22

以下是您使用volatile关键字的主要原因:

如果你有一些volatile ... x;,那么在线程B观察到分配之后,线程A在分配x = v;之前所做的任何事情对线程B都是可见的。

代码语言:javascript
复制
final XType v = ...;
volatile XType x = ...some value other than v...;
AType a;
BType b;
CType c;

在线程A中:

代码语言:javascript
复制
a = ...;
b = ...;
x = v;
c = ...;

在线程B中:

代码语言:javascript
复制
while (x != v) {
    ...sleep, or spin, or maybe do some useful work...
}
...guaranteed to see the new values of a, and b here.
...No guarantee about c. Could see the old value or the new value.

但请注意!触发该行为的是赋值x = v;

您的程序初始化volatile变量games,但是您的程序没有指定games的位置。程序中的任何东西都不会触发games的易失性。关键字在您的特定示例中不起作用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60772230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档