この記事では、マルチスレッドJavaのダウンロードについて説明します。次のように、参照のために共有してください。
マルチスレッドファイルを使用してファイルをダウンロードすると、ファイルのダウンロードをより速く完了できます。マルチスレッドファイルが高速である理由は、多くのサーバーリソースを占有しているためです。たとえば、サーバーが同時に最大100人のユーザーにサービスを提供し、サーバー内の1つのスレッドが1人のユーザーに対応するとします。 100個のスレッドはコンピューターで同時に実行されるのではなく、CPUによって順番に実行されます。アプリケーションAが99のスレッドを使用してファイルをダウンロードする場合、99人のユーザーのリソースを占有することに相当します。 1秒以内に各スレッドにCPUによって割り当てられた平均実行時間が10msであると仮定します。アプリケーションAは、サーバーで1秒で990msの実行時間を取得しますが、他のアプリケーションでは1秒で10ミリ秒の実行時間しかありません。蛇口と同じように、1秒あたりの水出力が等しい場合、10ミリ秒よりも990ミリ秒の水が間違いなくより多くの水です。
マルチスレッドダウンロードの実装プロセス:
1.最初にダウンロードしたファイルの長さを取得し、次にローカルファイルの長さを設定します。
httpurlconnection.getContentLength(); randomAccessFile file = new RandomAccessFile( "youdao.exe"、 "rw"); file.setLength(filesize); //ローカルファイルの長さを設定します
2。ファイルの長さとスレッドの数に基づいて、データの長さと各スレッドの場所をダウンロードすることを計算します。たとえば、ファイルの長さは6m、スレッドの数は3、次に各スレッドでダウンロードされたデータの長さは2mで、各スレッドがダウンロードを開始する場所は下の図に示されています。
3. httpの範囲ヘッダーフィールドを使用して、次のようなファイルのダウンロードを指定するなど、各スレッドのダウンロードを開始する場所を指定します。コードは次のとおりです。
コードコピーは次のとおりです。httpurlconnection.setRequestProperty( "range"、 "bytes = 2097152-");
4.ファイルを保存し、RandomAccessFileクラスを使用して、各スレッドがローカルファイルからデータの書き込みを開始する場所を指定します。
RandomAccessFile ThreadFile = new RandomAccessFile( "<Span style =" font-family:arial、helvetica、sans-serif; "> youdao.exe </span> <span style =" font-family:arial、helvetica、sans-serif; ">"、 "rw");ファイル内の場所
以下は特定の実装クラスです。
実装クラスを作成する前に、最初にサーバーにダウンロードされるファイルを配置して展開する必要があります。
ここにディレクトリd:/tomcat/apache-tomcat-7.0.37/webapps/doudouに掲載し、startup.batをd:/tomcat/apache-tomcat-7.0.37/binで開始します
1.downloadtest.java
パッケージwww.csdn.net.down; import java.io.file; Import java.io.fileinputStream; Import java.io.fileoutputStream; Import java.io.inputStream; Import Java.inputStream; Import Java.io.RandomAcssfile; Import Java.net.net.net.net.net.net.net.net java.net.malformedurlexception; import java.net.url; public class downloadloadtest {public file; public randomAccessFile AccessFile; //スレッドの数public static int threadnum = 3; //各スレッドは、int blocksizeのダウンロードを担当します。 //アクセスパスの作成パブリック文字列パス= "http:// localhost:8080/doudou/youdao.exe"; public static int threadcount; //数量public void testdown(){try {// url object url url = new url(path); // httpurlconnectionオブジェクトを作成しますhttpurlconnection httpurlconnection =(httpurlconnection)url .openconnection(); //リクエストを送信する方法を設定httpurlconnection.setRequestMethod( "get"); //リクエストタイムアウトhttpurlconnection.setConnectTimeout(5000)かどうかを設定します。 // httpurlconnection .setRequestProperty( "user-agent"、 "mozilla/5.0(互換; msie 10.0; windows nt 6.2; trident/6.0)"); //応答が成功するかどうか(httpurlconnection.getResponseCode()== 200){//ファイルサイズint size = httpurlconnection.getContentLength(); System.out.println( "ファイルサイズ" +サイズ); //ファイルファイルを作成= newファイル( "youdao.exe"); AccessFile = new RandomAccessFile(file、 "rwd"); //ファイルサイズAccessFile.setLength(size)を設定します。 //各スレッドのサイズをダウンロードblocksize = size / threadnum; // 3つのスレッドを開き、このファイルを操作します(int i = 1; i <= threadnum; i ++){// 1 2 3 //各スレッドの開始位置を計算しましたstartsize =(i -1) * blocksize; // end position int endize =(i) * blocksize; //スレッドが最後のスレッドである場合(i == threadnum){//ファイルサイズが計算されたエンド位置より大きいかどうかを決定します}} //各スレッドのランダム読み取りを作成しますrandomAccessfile threadaccessfile = new RandomAccessFile(file、 "rwd");新しいスレッド(new downloadThread(i、threadaccessfile、startsize、endize、path))。start(); }}} catch(malformedurlexception e){// dodo auto-enerated catch block e.printstacktrace(); } catch(ioException e){// todo auto-fenated catch block e.printstacktrace(); }} public static void main(string [] args){downloadTest downloadTest = new downloadTest(); //ダウンロードメソッドを呼び出してくださいdownloadtest.testdown(); }} class class downloadloadThread runnable {//ダウンロードファイルpublic randomacessfile accessfileのカプセル化; //各スレッドにはアクセスファイルファイルオブジェクトスレッド1スレッド2スレッドがあります。 public int endize; //ファイルのパスパスパブリック文字列パスをダウンロードします。 public int threadid; //スレッドの識別public lownloadThread(int threadid、randomAccessfile accessfile、int startsize、int endize、string path){this.threadid = threadid; this.accessfile = accessFile; this.startsize = startsize; this.endsize = endize; this.path = path; } @Override public void run(){// run method try {//ファイルを作成するswerchfile = newファイル(threadId + ".txt"); if(threadfile.exists()){//ファイルのコンテンツを読み取る//ファイルの入力ストリームfileinputStream fis = new fileinputStream(threadFile); //ツールクラスを使用して、バイトデータを読み取ります[] = StreamTools.istodata(FIS); // string string threadlen = new String(data)に変換します。 if((threadlen!= null)&&(! ""。equals(threadlen))){startsize = integer.valueof(threadlen); // 416Bugのエラーを解くif(startsize> endize){startsize = endize -1; }}} // urlオブジェクトurl url = new url(path);を作成します。 // httpurlconnectionオブジェクトを作成しますhttpurlconnection httpurlconnection =(httpurlconnection)url .openconnection(); //リクエストヘッダーhttpurlconnection.setRequestMethod( "get"); //リクエストタイムアウトhttpurlconnection.setConnectTimeout(5000)かどうかを設定します。 // httpurlconnection .setRequestProperty( "user-agent"、 "mozilla/5.0(互換; msie 10.0; windows nt 6.2; trident/6.0)"); //キー設定httpurlconnection.setRequestProperty( "range"、 "bytes =" + startsize + " - " + endize); //現在のスレッドSystem.out.println( "Current Swrew" + ThreadID + "のダウンロードStart Position:" + StartSize + "End Position:" + Endize)をダウンロードします。 //成功した応答//ランダム読み取りファイルの開始位置AccessFile.seek(StartSize); //対応するストリームオブジェクトを取得しますinputstream is = httpurlconnection.getInputStream(); //出力ストリームオブジェクトバイトバッファを作成[] = new Byte [1024]; int len = 0; int threadtotal = 0; //各スレッドがダウンロードされた後にレコードを保存/ while((len = is.read(buffer))!= -1){accessfile.write(buffer、0、len); threadtotal += len; //書き込みの長さを記録// xmlファイル//ファイルのダウンロードの長さをfileoutputStream fos = new fileoutputStream(threadFile); fos.write((threadtotal + "").getBytes()); fos.flush(); fos.close(); } AccessFile.Close(); is.close(); system.out.println(threadid + "スレッド実行が完了しました"); //スレッド操作同期(downloadtest.class){downloadloadtest.threadcount ++; if(downloadtest.threadcount> = downloadloadtest.threadnum){for(int i = 1; i <= downloadtest.threadnum; i ++){file file = new file(i+"。txt"); if(file.exists()){file.delete(); }}}}}} catch(malformedurlexception e){// todo auto-enerated catch block e.printstacktrace(); } catch(ioException e){// todo auto-fenated catch block e.printstacktrace(); }}}2。StreamTools.javaストリーミングツールのカプセル化
パッケージwww.csdn.net.down; import java.io.io.bytearrayoutputStream; Import java.io.ioexception; Import java.io.inputStream; public class streamtools {public static byte [] istodata(inputstream is)throws ioexception {// byterayoottutttrem bops =; //データバイトバッファーを読むためのバッファ領域[] = new byte [1024]; //長さの記録を読むint len = 0; //ループリーディングwhile((len = is.read(buffer))!= -1){bops.write(buffer、0、len); } //読み取りコンテンツをバイト配列バイトデータに変換します[] = bops.tobytearray(); bops.flush(); bops.close(); is.close();データを返す; }}この記事がみんなのJavaプログラミングに役立つことを願っています。