Użyłem executorservice do pobierania plików z różnych adresów URL jednocześnie, ale potrzeba czasu nie jest mała w porównaniu do sekwencyjnego pobierania; Dlatego chcę użyć rekurencji. Poniżej znajduje się kod, który ma być stosowany:

Klasa równoległa:

String[] links;
File[] files;

public Parallel(String[] link, File[] files) {
    this.links = link;
    this.files = files;
}

@Override
public void run() {
    try {
        for (int i = 0; i <= 3; i++) {
            URL url = new URL(links[i]);
            HttpURLConnection http = (HttpURLConnection) url.openConnection();
            double fileSize = (double) http.getContentLengthLong();
            BufferedInputStream bis = new BufferedInputStream(http.getInputStream());
            FileOutputStream fos = new FileOutputStream(this.files[i]);
            BufferedOutputStream bos = new BufferedOutputStream(fos, 600000);
            byte[] buffer = new byte[1024];
            double downloadedData = 0.00;
            int readData = 0;

            while ((readData = bis.read(buffer, 0, 1024)) >= 0) {
                bos.write(buffer, 0, readData);
                downloadedData += readData;
            }
            bos.close();
            bis.close();
            System.out.println(this.files[i] + " -> done");
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

W klasie głównej po prostu podaję linki i ścieżki do plików i uruchomić wykonanie

ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        Runnable worker = new Parallel(links, files);
        executor.execute(worker);
        executor.shutdown();

Każda pomoc jest mile widziana!

0
Jessica 29 październik 2020, 11:20

1 odpowiedź

Najlepsza odpowiedź

Nie używasz współbieżności właściwie tutaj.

Co powinieneś zrobić, to coś takiego:

String link;
File file;

public Parallel(String link, File file) {
    this.link = link;
    this.file = files;
}

@Override
public void run() {
    try {
        URL url = new URL(link);
        HttpURLConnection http = (HttpURLConnection) url.openConnection();
        double fileSize = (double) http.getContentLengthLong();
        BufferedInputStream bis = new BufferedInputStream(http.getInputStream());
        FileOutputStream fos = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(fos, 600000);
        byte[] buffer = new byte[1024];
        double downloadedData = 0.00;
        int readData = 0;

        while ((readData = bis.read(buffer, 0, 1024)) >= 0) {
            bos.write(buffer, 0, readData);
            downloadedData += readData;
        }
        bos.close();
        bis.close();
        System.out.println(file + " -> done");
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

I wtedy:


String[] links;
File[] files;

//...

ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

for (int i = 0; i <= 3; i++) {
    Runnable worker = new Parallel(links[i], files[i]);
    executor.execute(worker);
}
executor.shutdown();

Następnie każde pobranie rzeczywiście otrzyma własną wątek.

W twoim przypadku wszystkie pobieranie otrzymują jeden wątek, w którym wszystko się dzieje kolejno.

1
Tarmo 29 październik 2020, 08:45