重用线程下载下一个文件段

时间:2014-08-24 07:28:43

标签: java performance javafx nio apache-httpclient-4.x

我正在寻找可以提高下载速度和提高CPU,内存性能的可能方法。目前我正在分段下载文件并使用java nio transferFrom函数传输数据。

public void startDownload() {
    threadService.execute(() -> {
        double currentBytes = bytesDone.doubleValue();
        //Download each segment independently.
        for (int i = 0; i < segments; i++) {
            if (intialState[i] != -1) {
                threadService.execute(new Segment((i * sizeOfEachSegment)
                        + intialState[i], (i + 1) * sizeOfEachSegment, i));
            }
        }

        if (intialState[segments] != -1) {
            threadService.execute(new Segment((segments * sizeOfEachSegment)
                    + intialState[segments], sizeofFile, segments));
        }

        // Keep saving states of threads. And updating speed.
        while (bytesDone.get() < sizeofFile) {
            for (int i = 0; i < 1; i++) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException ex) {
                    System.out.println("thread interupted while sleeping");
                }

                System.out.println(speed
                        = (int) ((bytesDone.doubleValue() - currentBytes) / 5120));
                currentBytes = bytesDone.doubleValue();
                avgSpeed[0] += speed;
                avgSpeed[1]++;

            }
            states.saveState(stateArray, currentState);
        }
        // Download Complete.
        try {
            fileChannel.close();
            file.close();
        } catch (IOException ex) {
            System.out.println("failed to close file");
        }
        currentState.set(2);
        states.saveState(stateArray, currentState);
        System.out.println("Alhamdullilah Done :)");
        System.out.println("Average Speed : " + avgSpeed[0] / avgSpeed[1]);
    });
}

public class Segment implements Runnable {

    long start;
    long end;
    long delta;
    int name;

    public Segment(long start, long end, int name) {
        this.start = start;
        this.end = end;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            HttpGet get = new HttpGet(uri);
            // Range header for defining which segment of file we want to receive.
            String byteRange = start + "-" + end;
            get.setHeader("Range", "bytes=" + byteRange);
            try (CloseableHttpResponse response = client.execute(get)) {
                ReadableByteChannel inputChannel = Channels.newChannel(
                        response.getEntity().getContent());

                while (start < end && currentState.get() == 1) {
                    delta = fileChannel.transferFrom(inputChannel, start, 8192);
                    start += delta;
                    bytesDone.addAndGet(delta);
                    stateArray.set(name, start);
                }

                stateArray.set(name, -1);
            }
            System.out.println("Thread done: " + name);

        } catch (IOException ex) {
            System.out.println("thread " + name + " failed to download");

        }
    }
}

此实现提供400+ kb / s但Internet Download Manager以500+ kb / s的速度下载相同的文件。 有没有我可以重用的资源(我注意到每个连接最初需要时间才能达到其最大速度,所以有任何方法我可以重复使用相同的线程下载前一个文件的下一部分)?

0 个答案:

没有答案