多个线程下载同一个资源文件
一个线程下载一部分
package sqy;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author suqinyi
* @Date 2021/7/1
*/
public class DownloadUnite {
static ReentrantLock lock = new ReentrantLock();
//此方法用于获取一个HttpURLConnection对象
public static HttpURLConnection getConn() throws Exception {
String path = "https://www.baidu.com/img/flexible/logo/pc/result.png";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setRequestProperty("Accept", "application/x-jpg");
return conn;
}
//此方法用于创建多线程并且进行下载
public void download() throws Exception {
RandomAccessFile file = new RandomAccessFile("picture.jpg", "rw");
HttpURLConnection conn = DownloadUnite.getConn();
int size = conn.getContentLength();
conn.disconnect();
int parts = size / (4 * 1024);
DownloadThread[] thread = new DownloadThread[4];
int starts;
int ends;
System.out.println(size);
for (int i = 0; i < 4; i++) {
starts = i * parts * 1024;
ends = (i + 1) * parts * 1024 - 1;
if (i == 3) {
ends = size;
}
thread[i] = new DownloadThread(starts, ends, file);
thread[i].start();
}
}
//将循环读取IO流的操作写入read方法中,用于加锁
public static int read(int starts, int ends, RandomAccessFile file, InputStream pip) throws Exception {
lock.lock();
int hasRead = 0;
byte[] buffer = new byte[1024];
file.seek(starts);
hasRead = pip.read(buffer);
starts += hasRead;
file.write(buffer, 0, hasRead);
lock.unlock();
return starts;
}
//多线程下载类
class DownloadThread extends Thread {
int starts;
int ends;
RandomAccessFile file;
public DownloadThread(int starts, int ends, RandomAccessFile file) {
this.starts = starts;
this.ends = ends;
this.file = file;
}
public void run() {
try {
HttpURLConnection conn = (HttpURLConnection) DownloadUnite.getConn();
InputStream pip = conn.getInputStream();
pip.skip(starts);
while ((ends - starts) > 0) {//此方法用于加锁
starts = DownloadUnite.read(starts, ends, file, pip);
}
System.out.println(starts);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//主方法用于运行程序
public static void main(String[] args) throws Exception {
new DownloadUnite().download();
}
}
效果: