首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何保证AtomicLong addAndGet结果的正确性

如何保证AtomicLong addAndGet结果的正确性
EN

Stack Overflow用户
提问于 2018-06-01 06:33:30
回答 2查看 122关注 0票数 1

我要计算当前百分比在我的多线程下载programme.But有一个奇怪的问题。第二次下载期间的lastDownloadSize必须是lastDown的写和lastDownloadSize之和。示例

这是我的密码

代码语言:javascript
运行
复制
private long getDownloadSize() {
    synchronized (this) {
        final AtomicLong totalWriteCount = new AtomicLong(0);
        final AtomicLong lastDownloadSize = new AtomicLong(0);
        for (DownloadTask task : downloadTasks) {
            final long writeCount = task.getWriteCount();
            totalWriteCount.addAndGet(writeCount);
            final long downloadSize = task.getPosition().getDownloadSize();
            lastDownloadSize.addAndGet(downloadSize);
        }
        System.out.println("=====  writeCount : " + totalWriteCount + "lastDownloadSize : " + lastDownloadSize);
        return totalWriteCount.addAndGet(lastDownloadSize.get());
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-01 06:45:19

totalWriteCountlastDownloadSize变量是getDownloadSize()方法的局部变量。在这种情况下,使用AtomicLong没有意义,因为只有一个线程可以访问它们。

您可能的意思是,让totalWriteCountlastDownloadSize成为您类的成员:

代码语言:javascript
运行
复制
class SomeClass {
    // ...
    final AtomicLong totalWriteCount = new AtomicLong(0);
    final AtomicLong lastDownloadSize = new AtomicLong(0);
    // ...

    private long getDownloadSize() {
        synchronized (this) {
            for (DownloadTask task : downloadTasks) {
                final long writeCount = task.getWriteCount();
                totalWriteCount.addAndGet(writeCount);
                final long downloadSize = task.getPosition().getDownloadSize();
                lastDownloadSize.addAndGet(downloadSize);
            }
            System.out.println("=====  writeCount : " + totalWriteCount + "lastDownloadSize : " + lastDownloadSize);
            return totalWriteCount.addAndGet(lastDownloadSize.get());
        }
    }
}

但是,在这种情况下,如果只从synchronized(this)块中访问它们,则不需要使用AtomicLong块,因为同步块已经确保它们仅由单个线程同时访问。

票数 1
EN

Stack Overflow用户

发布于 2018-06-01 06:46:41

您的当前设置无法工作,因为您使用AtomicLong的方式不对。在单个线程中定义任何Atomic-class都是对该API的错误使用。

为什么我说单线程,当有人进入您的方法时,您正在同步,这只是说一次只有一个线程可以使用所述的方法。这就引出了一个问题:

  • AtomicLong是一个局部变量

您可能希望将downloadSizetotalWriteCount定义为class的成员。例如:

代码语言:javascript
运行
复制
public class YourClass {
    private final AtomicLong totalWriteCount = new AtomicLong(0);        
    private final AtomicLong downloadSize = new AtomicLong(0);

    /* constructors and other methods */

    private synchronized long getDownloadSize() {
        for (DownloadTask task : downloadTasks) {
            final long writeCount = task.getWriteCount();
            totalWriteCount.addAndGet(writeCount);
            final long downloadSize = task.getPosition().getDownloadSize();
            lastDownloadSize.addAndGet(downloadSize);
        }
        System.out.println("=====  writeCount : " + totalWriteCount + "lastDownloadSize : " + lastDownloadSize);
        return totalWriteCount.addAndGet(lastDownloadSize.get());
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50637384

复制
相关文章

相似问题

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