多线程测试

This commit is contained in:
lushunming 2025-06-24 14:15:39 +08:00
parent 989157a852
commit e41998b0c5
3 changed files with 218 additions and 0 deletions

View File

@ -0,0 +1,25 @@
package com.github.catvod.utils;
import java.util.List;
public class DownloadInfo {
private List<long[]> parts;
private String url;
public List<long[]> getParts() {
return parts;
}
public void setParts(List<long[]> parts) {
this.parts = parts;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}

View File

@ -0,0 +1,168 @@
package com.github.catvod.utils;
import com.github.catvod.crawler.SpiderDebug;
import com.github.catvod.net.OkHttp;
import okhttp3.Response;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
public class DownloadService {
private static final int THREAD_NUM = 16;
//最小分片按这个下载
private static final int PER_PIECE = 1024 * 1024;
//按照这个分割视频每一个部分多线程下载下载完下载下一个部分
private static final int PER_PART = 1024 * 1024 * THREAD_NUM;
private List<Future<Response>> results = new ArrayList<Future<Response>>();
private RandomAccessFile file = null;
private List<long[]> parts;
private AtomicInteger index = new AtomicInteger(0);
private static class Loader {
static volatile DownloadService INSTANCE = new DownloadService();
}
public static DownloadService get() {
return DownloadService.Loader.INSTANCE;
}
/**
* 下载链接
*/
private String url;
/**
* 下载信息
*/
private DownloadInfo downloadInfo;
public void submitDownload(String url, Map<String, String> headers, long length) {
if (url.equals(this.url)) {
SpiderDebug.log("url相同任务已存在");
} else {
this.url = url;
parts = generatePart(length);
downloadInfo = new DownloadInfo();
downloadInfo.setParts(parts);
downloadInfo.setUrl(url);
new Thread(new Runnable() {
@Override
public void run() {
ExecutorService service = Executors.newFixedThreadPool(THREAD_NUM);
for (long[] part : parts) {
String newRange = "bytes=" + part[0] + "-" + part[1];
SpiderDebug.log("下载开始" + ";newRange:" + newRange);
Map<String, String> headerNew = new HashMap<>(headers);
headerNew.put("range", newRange);
headerNew.put("Range", newRange);
Future<Response> result = service.submit(() -> {
try {
part[2] = 1;
return OkHttp.newCall(url, headerNew);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
results.add(result);
}
try {
file = new RandomAccessFile(Path.tv() + File.separator + Util.MD5(url) + ".mp4", "rw");
} catch (FileNotFoundException e) {
SpiderDebug.log("创建文件失败");
throw new RuntimeException(e);
}
while (index.get() < results.size()) {
Response response = null;
try {
response = results.get(index.get()).get();
file.seek(parts.get(index.get())[0]);
file.write(response.body().bytes());
index.addAndGet(1);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
service.shutdown();
}
}).start();
}
}
/**
* 返回信息
*
* @param start 开始
* @return
*/
public Object[] getDownloadBytes(long start) throws ExecutionException, InterruptedException {
long partIndex = start / PER_PART;
while (parts.get((int) partIndex)[2] == 0) {
index.set((int) partIndex);
}
try {
file.seek(start);
byte[] bytes = new byte[Math.toIntExact(parts.get((int) partIndex)[1] - start + 1)];
file.read(bytes);
return new Object[]{bytes,start,parts.get((int) partIndex)[1] };
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 分割为需要下载的部分
*
* @param total 文件总大小
* @return
*/
private static List<long[]> generatePart(long total) {
SpiderDebug.log("generatePart.total:" + total);
long start = 0;
long end = total - 1;
//分割为多少个部分
long size = total / PER_PART;
SpiderDebug.log("generatePart.size:" + size);
List<long[]> partList = new ArrayList<>();
for (int i = 0; i < size * THREAD_NUM; i++) {
long partEnd = Math.min(start + PER_PIECE, end);
partList.add(new long[]{start, partEnd, 0});
start = partEnd + 1;
}
//最后多出分为一块下载
if (start <= end) {
partList.add(new long[]{start, end, 0});
}
return partList;
}
}

View File

@ -0,0 +1,25 @@
package com.github.catvod.utils;
import com.github.catvod.server.Server;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.HashMap;
@RunWith(RobolectricTestRunner.class)
public class ProxyVideoTest {
@Test
public void proxyMultiThread() {
// ProxyVideo.proxyMultiThread()
Server.get().start();
String url = ProxyVideo.buildCommonProxyUrl(
"http://172.16.1.217:18089/ng-grid/video.mp4", new HashMap<>());
System.out.println(url);
while (true) {
}
}
}