我的问题是关于如何使用同步块的,我的类FileAdapter有一个方法write,它接收用于下载文件的HTTP连接结果的InputStream,对于下载并写入磁盘的每千字节,它调用接收到的DownloadReport类实例的download方法,以传递已下载的内容。 在另一个将输出输出给用户的Thread中,它调用了updateProgress方法,也就是DownloadReport的方法。
类,此方法负责更新在终端上显示给用户的进度条。
这个问题将是,如果FileAdapter类尝试更新的字节数下载只是当输出线程试图更新进度条,因为这两种方法编辑变量的值intermediateDownloaded,它只能作为一个辅助变量,举行自上次更新以来下载的字节数,以计算下载速度。
如果我在downloaded和updateProgress方法中使用“ synchronized(this)”块,它将阻止整个类DownloadReport和输出线程将只能在 FileAdapter类更新下载的字节数之后更新进度条吗?
FileAdapter:
public void write(InputStream content, DownloadReport downloadReport) throws IOException {
FileOutputStream output = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int read;
while ((read = content.read(buffer)) != -1) {
output.write(buffer, 0, read);
downloadReport.downloaded(read);
}
}
下载报告:
public void downloaded(int bytes) {
intermediateDownloaded += bytes;
downloaded += bytes;
}
public void updateProgress() {
long now = System.currentTimeMillis();
double delta = UnitHelper.sizeRound(((now - lastTimeUpdate) / 1000.0), 2);
if (delta >= 1) {
unitAdapter.convertSpeed(intermediateDownloaded, delta);
intermediateDownloaded = 0;
lastTimeUpdate = now;
}
progressBar.updateProgress(unitAdapter.finalSize,
unitAdapter.recalculate(downloaded), unitAdapter.unity);
}
问题来源:Stack Overflow
首先,在最近十年或更长时间里,这种类型的同步已不合时宜,因为:
现在,如果您坚持以这种方式进行操作,那将synchronize( this )是一个坏主意,因为拥有对象引用的人也可以这样做synchronized( yourObject ),那么您将陷入僵局。synchronized方法也是如此,因为编译器是在后台使用它们来实现它们synchronized( this )的。因此,也不要这样做。始终声明一个私有对象以用作锁。
同样,您似乎已经了解,同步锁需要尽可能少地处于活动状态,以避免阻塞可能也需要获取该锁的其他线程。因此,它需要包装尽可能少的指令。
对于您的代码,如果我理解正确,则需要执行以下操作:
private final Object lock = new Object();
public void downloaded( int bytes )
{
synchronized( lock )
{
downloaded += bytes;
}
}
然后在访问时进一步向下移动,downloaded还必须与同步lock,并且您需要找到其他方法来仅intermediateDownloaded基于该方法来计算您的怪异变量downloaded,这样就不必参与同步。
回答来源:Stack Overflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。