我将从管理所有下载的DownloadManager开始。
interface DownloadManager{ public InputStream registerDownload(InputStream stream);}希望参与托管带宽的所有代码都将在开始从下载管理器中读取之前将其流注册到下载管理器中。在它的registerDownload()方法中,管理器将给定的输入流包装在中
ManagedBandwidthStream。
public class ManagedBandwidthStream extends InputStream { private DownloadManagerImpl owner; public ManagedBandwidthStream( InputStream original, DownloadManagerImpl owner ) { super(original); this.owner = owner; } public int read(byte[] b, int offset, int length) { owner.read(this, b, offset, length); } // used by DownloadManager to actually read from the stream int actuallyRead(byte[] b, int offset, int length) { super.read(b, offset, length); } // also override other read() methods to delegate to the read() above }该流确保将对read()的所有调用都定向回下载管理器。
class DownloadManagerImpl implements DownloadManager{ public InputStream registerDownload(InputStream in) { return new ManagedDownloadStream(in); } void read(ManagedDownloadStream source, byte[] b, int offset, int len) { // all your streams now call this method. // You can decide how much data to actually read. int allowed = getAllowedDataRead(source, len); int read = source.actuallyRead(b, offset, len); recordBytesRead(read); // update counters for number of bytes read }}然后,您的带宽分配策略就是有关如何实现getAllowedDataRead()的。
限制带宽的一种简单方法是,在给定时间段(例如1秒)内保留一个计数器,可以读取多少个字节。每次读取调用都会检查计数器,并使用该计数器限制读取的实际字节数。计时器用于重置计数器。
实际上,在多个流之间分配带宽可能会变得非常复杂,尤其是为了避免饥饿并促进公平,但这应该为您提供一个良好的开端。



