java 竞争条件_Java代码竞争条件多线程?

我有一些代码,我想知道在多线程环境中我是否会丢失数据......

以下是示例代码:

public class TestingJavaThreading {

private final Map> data = Maps.newConcurrentMap();

private final HttpClient client;

private final AsyncDataProvider provider;

private final String baseUrl;

// This method is called first...

public void init(String code) {

// We initialise the set to ensure it doesn't throw a null pointer exception or something weird...

data.put(code, Sets.newConcurrentHashSet());

// We tell the provider we're interested in data...

provider.subscribeToDataFrom(code);

// This HTTP call may take long time, and we can't afford losing data, that's why we subscribed beforehand in the previous line...

List elements = client.request(baseUrl + code);

// We add all of the new elements, meanwhile some elements may have been added by "onMessageFromProvider"

data.get(code).addAll(elements);

data.get(code)

.stream()

.map( /* some transformations here, whatever... */)

.forEach(e -> System.out.println(e));

// Now we've printed the merged data from "onMessageFromProvider" + the HTTP call

// We remove the element from the map, so now we only receive data from "onMessageFromProvider"

data.remove(code);

}

public void onMessageFromProvider(String code, String element) {

final Set newSet = data.computeIfPresent(code, (k, v) -> {

v.add(element);

return v;

});

if (newSet == null) {

// Do something else...

}

}

}

基本上,被调用的初始方法是init。步骤是这样的:

初始化CHM以确保其包含数据

我们有一个提供商,可以实时提供有关该元素的信息,但它不提供过去的数据。当数据来自提供者时,它调用方法“onMessageFromProvider”

为了获取项目的先前数据,我们需要进行单独的HTTP调用,然后将来自“onMessageFromProvider”的数据与来自HTTP调用的结果合并。完成之后,我们可以完全依赖“onMessageFromProvider”正在做的事情

一旦我们得到HTTP调用的结果,我们将它与来自“onMessageFromProvider”的数据合并,同时,我们应用转换,并打印生成的合并集

现在我们删除了地图密钥,因此我们可以完全依赖“onMessageFromProvider”正在做的事情

醇>

在步骤(3)运行时,这是否会导致数据丢失?我该如何解决?我应该在哪里放置更多代码,以尽可能少地依赖synchronished?

所以恢复,我的目标是永远不会丢失数据,我想确保我的算法100%保证。

对于loooong帖子感到抱歉,希望它有意义。

更新

根据输入,我用实际样本更新代码,目前看起来像这样:

public class Main {

public static void main(String[] args) throws InterruptedException {

new Main().init("X");

}

public void init(String code) throws InterruptedException {

subscribeToDataFrom(code);

CompletableFuture

.supplyAsync(getDataFromHttpRequest());

}

private Supplier> getDataFromHttpRequest() {

return () -> {

Set resultsToReturn = Sets.newHashSet();

try {

resultsToReturn.add("B");

resultsToReturn.add("C");

resultsToReturn.add("D");

resultsToReturn.add("E");

resultsToReturn.add("F");

Thread.sleep(1000); // Simulate it is a slow request...

} catch (Exception ex) {}

return resultsToReturn;

};

}

private void subscribeToDataFrom(String code) {

Runnable r = () -> {

while (true) {

onMessageFromProvider(code, UUID.randomUUID().toString());

}

};

new Thread(r).start();

new Thread(r).start();

new Thread(r).start();

new Thread(r).start();

new Thread(r).start();

}

public void onMessageFromProvider(String code, String element) {

// Here how do I create the completable future for usage in the previous CompletableFuture????

final Set newSet = data.computeIfPresent(code, (k, v) -> {

v.add(element);

return v;

});

if (newSet == null) {

System.out.println("Ok, now I can do something different with: " + element);

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值