我想在我的多线程下载程序中计算当前百分比。但是有一个奇怪的问题。 第二次下载期间的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());
}
}
答案 0 :(得分:1)
您的totalWriteCount
和lastDownloadSize
变量是getDownloadSize()
方法的局部变量。在这种情况下,使用AtomicLong
没有意义,因为只有一个线程可以访问它们。
您可能想要的是让您的班级成员totalWriteCount
和lastDownloadSize
成员:
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
,因为synchronized块已经确保它们仅被访问一个单独的线程同时。
答案 1 :(得分:1)
您当前的设置无效,因为您以错误的方式使用AtomicLong
。在单个线程中定义任何Atomic
- 类只是对该API的误用。
现在为什么我说单线程,当你有人输入你的方法时你正在进行同步,这只是说一次只有一个线程可以使用所述方法。这引出了我们的问题:
AtomicLong
是一个本地变量您可能希望将downloadSize
和totalWriteCount
定义为class
的成员。 E.g:
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());
}
}