Artikel ini menjelaskan unduhan Java multi-threaded. Bagikan untuk referensi Anda, sebagai berikut:
Menggunakan file multi-threaded untuk mengunduh file dapat menyelesaikan unduhan file lebih cepat. Alasan mengapa file multi-threaded cepat adalah karena mereka menempati banyak sumber daya server. Misalnya: Misalkan server melayani hingga 100 pengguna secara bersamaan, dan satu utas di server sesuai dengan satu pengguna. 100 utas tidak dieksekusi secara bersamaan di komputer, tetapi dieksekusi secara bergantian oleh CPU. Jika aplikasi A menggunakan 99 utas untuk mengunduh file, itu setara dengan menempati sumber daya 99 pengguna. Misalkan waktu eksekusi rata -rata yang dialokasikan oleh CPU untuk setiap utas dalam satu detik adalah 10ms. Aplikasi A memperoleh waktu eksekusi 990ms dalam satu detik di server, sementara aplikasi lain hanya memiliki waktu eksekusi 10ms dalam satu detik. Sama seperti keran, ketika output air per detik sama, itu jelas lebih banyak air selama 990 milidetik daripada selama 10 milidetik.
Proses implementasi unduhan multi-threaded:
1. Pertama dapatkan panjang file yang diunduh, lalu atur panjang file lokal.
HttpUrlConnection.getContentLength (); acakeAccessFile file = new acakeAccessFile ("yodao.exe", "rw"); file.setLength (filesize); // Atur panjang file lokal2. Hitung panjang data dan unduh lokasi setiap utas berdasarkan panjang file dan jumlah utas. Sebagai contoh: panjang file adalah 6m dan jumlah utas adalah 3, maka panjang data yang diunduh oleh setiap utas adalah 2m, dan lokasi di mana setiap utas mulai mengunduh ditampilkan pada gambar di bawah ini.
3. Gunakan bidang header range HTTP untuk menentukan dari mana setiap utas mulai mengunduh, seperti: Tentukan file unduhan dari posisi 2m file, kode adalah sebagai berikut:
Salinan kode adalah sebagai berikut: httpurlConnection.setRequestProperty ("range", "bytes = 2097152-");
4. Simpan file dan gunakan kelas acak ACCACESSFILE untuk menentukan di mana setiap utas mulai menulis data dari dalam file lokal.
RandomAccessFile threadFile = baru acak AccessFile ("<span style =" font-family: Arial, helvetica, sans-serif; "> youdao.exe </span> <span style =" font-family: Arial, helvetica, sans-serif; ">", "rw"); </sang sange/helvetica, sans-erif; ">" fileBerikut ini adalah kelas implementasi spesifik:
Sebelum menulis kelas implementasi, pertama -tama kita harus menempatkan file yang akan diunduh di server dan menggunakan:
Saya meletakkannya di sini di direktori D: /Tomcat/apache-tomcat-7.0.37/webapps/doudou dan mulai startup.bat di bawah d: /tomcat/apache-tomcat-7.0.37/bin
1.DownloadTest.java
Paket www.csdn.net.down; import java.io.file; impor java.io.fileinputStream; import java.io.fileoutputstream; impor java.io.ioException; impor impor; java.net.malformedurlexception; import java.net.url; kelas publik unduhloadTest {file file publik; public accessAccessFile Accessfile; // Jumlah utas statis int threadnum public = 3; // Setiap utas bertanggung jawab untuk mengunduh int blocksize; // Buat jalur akses public string path = "http: // localhost: 8080/doudou/youdao.exe"; public static int threadCount; // kuantitas public void testdown () {try {// buat url objek url url = URL baru (path); // Buat httpurlConnection objek httpurlconnection httpurlconnection = (httpurlConnection) url .openconnection (); // Atur metode pengiriman permintaan httpurlconnection.setRequestMethod ("get"); // Tetapkan apakah batas waktu permintaan httpurlconnection.setConnecttimeout (5000); // atur httpurlconnection .setRequestProperty ("User-agent", "Mozilla/5.0 (kompatibel; MSIE 10.0; Windows NT 6.2; Trident/6.0)"); // apakah respons berhasil if (httpurlConnection.getResponsecode () == 200) {// Dapatkan ukuran file ukuran int = httpurlConnection.getContentLength (); System.out.println ("Ukuran File" + ukuran); // Buat file file = file baru ("youdao.exe"); AccessFile = baru acakAccessFile (file, "rwd"); // atur ukuran file accessFile.setLength (size); // Unduh ukuran setiap thread blocksize = size / threadnum; // Buka tiga utas untuk mengoperasikan file ini untuk (int i = 1; i <= threadnum; i ++) {// 1 2 3 // Hitung posisi awal setiap utas int startize = (i - 1) * blocksize; // posisi akhir int endsize = (i) * blocksize; // Saat utas adalah utas terakhir jika (i == threadnum) {// Tentukan apakah ukuran file lebih besar dari posisi akhir yang dihitung jika (ukuran> endsize) {// posisi akhir sama dengan ukuran file endssize = size; }} // Buat bacaan acak untuk setiap utas acak AccomeAccessFile threadAccessFile = baru acakAccessFile (file, "rwd"); utas baru (unduhan baru (i, threadAccessFile, startize, endsize, path)). start (); }}} catch (MalFormedurlexception e) {// TODO Auto-Encanerated Catch Block E.PrintStackTrace (); } catch (ioException e) {// TODO AUTO-ENCEALATED Catch Block E.PrintStackTrace (); }} public static void main (string [] args) {downloadtest downloadTest = new downloadTest (); // hubungi metode unduh downloadtest.testdown (); }} class downloadLoadTread mengimplementasikan runnable {// enkapsulasi file unduhan public acakAccessFile accessFile; // Setiap utas memiliki Objek File AccessFile Thread1 Thread2 Thread3 // Posisi Mulai dari File Unduh Utas Unduh Int Publik dimulai; Int publik Endssize; // jalur path dari file download public string path; Publik int threadid; // Identifikasi Thread Public DownloadThread (int threadId, acak ACCEACCESSFILE AccessFile, int dimulai, int endsize, string path) {this.threadid = threadId; this.accessFile = AccessFile; this.startSize = dimulai; this.endSize = endssize; this.path = path; } @Override public void run () {// Jalankan metode run coba {// buat file file threadFile = file baru (threadId + ".txt"); if (threadFile.exists ()) {// Baca konten file // Buat file input file input fileInputStream fis = new FileInputStream (threadFile); // Gunakan kelas alat untuk membaca data byte [] = streamTools.istodata (FIS); // konversi ke string string threadlen = string baru (data); if ((threadlen! = null) && (! "". Equals (threadlen))) {startize = integer.valueof (threadlen); // Selesaikan kesalahan 416Bug if (startize> endsize) {startize = endsize - 1; }}} // Buat url url url url = URL baru (path); // Buat httpurlConnection objek httpurlconnection httpurlconnection = (httpurlConnection) url .openconnection (); // atur header permintaan httpurlconnection.setRequestMethod ("get"); // Tetapkan apakah batas waktu permintaan httpurlconnection.setConnecttimeout (5000); // atur httpurlconnection .setRequestProperty ("User-agent", "Mozilla/5.0 (kompatibel; MSIE 10.0; Windows NT 6.2; Trident/6.0)"); // Pengaturan Kunci httpurlconnection.setRequestProperty ("range", "bytes =" + startize + "-" + endssize); // output System thread saat ini.out.println ("Thread saat ini" + threadId + "Unduh posisi mulai:" + Memulai + "Unduh posisi akhir:" + endSsize); // Respons Sukses // Atur posisi mulai dari file baca acak AccessFile.seek (startize); // Dapatkan inputStream objek aliran yang sesuai adalah = httpurlConnection.getInputStream (); // Buat Buffer Byte Object Objek Output [] = byte baru [1024]; int len = 0; int threadtotal = 0; // Simpan catatan setelah setiap utas diunduh/ while ((len = is.read (buffer))! = -1) {accessFile.write (buffer, 0, len); ThreadTotal += len; // Catat panjang yang Anda tulis // file xml // Catat panjang unduhan file melalui file fileoutputStream fos = new fileoutputStream (threadFile); fos.write ((threadtotal + "") .getbytes ()); fos.flush (); fos.close (); } accessFile.close (); is.close (); System.out.println (ThreadID + "Eksekusi Thread selesai"); // Operasi utas disinkronkan (downloadtest.class) {downloadtest.threadcount ++; if (downloadtest.threadcount> = downloadtest.threadnum) {for (int i = 1; i <= downloadtest.threadnum; i ++) {file file = file baru (i+". txt"); if (file.exists ()) {file.delete (); }}}}} catch (MalFormedurlexception e) {// TODO Auto-Eynerated Catch Block E.PrintStackTrace (); } catch (ioException e) {// TODO AUTO-ENCEALATED Catch Block E.PrintStackTrace (); }}}2. StreamTools.java Enkapsulasi alat streaming
package www.csdn.net.down;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;public class StreamTools { public static byte[] isToData(InputStream is) throws IOException{ // ByteArrayOutputStream bops = new BytearrayoutputStream (); // area buffer untuk membaca buffer byte data [] = byte baru [1024]; // Baca Panjang Rekaman int len = 0; // loop bacaan while ((len = is.read (buffer))! = -1) {bops.write (buffer, 0, len); } // Konversi konten yang dibaca menjadi data byte byte byte [] = bops.tobyteArray (); bops.flush (); bops.close (); is.close (); pengembalian data; }}Saya harap artikel ini akan membantu pemrograman Java semua orang.