如何保证AtomicLong addAndGet结果的正确性
How to ensure the correctness of AtomicLong addAndGet result
我想计算我的多线程下载中的当前百分比programme.But有一个奇怪的问题。
第二次下载时的lastDownloadSize必须是lastDown的write和lastDownloadSize之和。
example
有我的代码
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());
}
}
你的totalWriteCount
和lastDownloadSize
变量是getDownloadSize()
方法的局部变量。在那种情况下,使用 AtomicLong
没有意义,因为只有一个线程可以访问它们。
您的意思可能是让 totalWriteCount
和 lastDownloadSize
成为您的 class:
的成员
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
s,因为同步块已经确保它们仅在由一个线程同时访问。
您当前的设置不起作用,因为您使用 AtomicLong
的方式不对。在单个线程中定义任何 Atomic
-class 只是滥用 API.
为什么我说单线程,当有人进入你的方法时你正在同步,这只是说一次只有一个线程可以使用所述方法。这导致我们遇到问题:
AtomicLong
是局部变量
您可能想将 downloadSize
和 totalWriteCount
定义为 class
的 成员。例如:
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());
}
}
我想计算我的多线程下载中的当前百分比programme.But有一个奇怪的问题。 第二次下载时的lastDownloadSize必须是lastDown的write和lastDownloadSize之和。 example
有我的代码
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());
}
}
你的totalWriteCount
和lastDownloadSize
变量是getDownloadSize()
方法的局部变量。在那种情况下,使用 AtomicLong
没有意义,因为只有一个线程可以访问它们。
您的意思可能是让 totalWriteCount
和 lastDownloadSize
成为您的 class:
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
s,因为同步块已经确保它们仅在由一个线程同时访问。
您当前的设置不起作用,因为您使用 AtomicLong
的方式不对。在单个线程中定义任何 Atomic
-class 只是滥用 API.
为什么我说单线程,当有人进入你的方法时你正在同步,这只是说一次只有一个线程可以使用所述方法。这导致我们遇到问题:
AtomicLong
是局部变量
您可能想将 downloadSize
和 totalWriteCount
定义为 class
的 成员。例如:
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());
}
}