我有一项长期的任务,就是创建一个位图并保存它,然后重新创建更多的位图,这是我在一个后台线程上做的
ExecutorService executor = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());
executor.execute(() -> {...bitmap work ...}
但是处理所有位图需要很长时间,所以我创建了一个线程池来使用多线程来加速任务.
private final int cores = Runtime.getRuntime().availableProcessors();
private final ExecutorService executor = Executors.newFixedThreadPool(cores + 1);
for (int i = 0; i < totalPage; i++) {
Runnable runnable = () -> {...bitmap work ...}
executor.submit(runnable);
}
但每当我使用超过1个线程时,它就会在某个任务上随机卡住(比如127个线程中有7个),没有错误或任何它无法处理的任务.我可以在executor队列中查看挂起的任务.但是,如果我将线程池更改为使用1个线程,它可以毫无问题地工作并处理所有任务.
下面是完整的实际代码
ExecutorService executor = Executors.newFixedThreadPool(cores + 1);
List<Future<?>> futureList = new ArrayList<>();
boolean allDone = false;
try {
//Convert pdf to Bitmap
ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor.open(new File(pdfFileName), ParcelFileDescriptor.MODE_READ_ONLY);
PdfRenderer pdfRenderer = new PdfRenderer(parcelFileDescriptor);
int totalPage = pdfRenderer.getPageCount();
final int[] counter = {1};
for (int i = 0; i < totalPage; i++) {
int finalI = i;
String finalOriginalPdfName = originalPdfName;
String finalGeneratedPdfName = generatedPdfName;
Runnable runnable = () -> {
//pd.setMessage("Processing page " + (finalI + 1) + " of " + totalPage);
PdfRenderer.Page page = pdfRenderer.openPage(finalI);
Bitmap pageBitmap = Bitmap.createBitmap((300 * page.getWidth()) / 72, (300 * page.getHeight()) / 72, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(pageBitmap);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(pageBitmap, 0, 0, null);
page.render(pageBitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_PRINT);
page.close();
//Crop bitmaps and temporarily store on app data directory
for (int k = 0; k < SlipBoundingBox.Y.length; k++) {
for (int j = 0; j < SlipBoundingBox.X.length; j++) {
Bitmap slipBitmap = Bitmap.createBitmap(pageBitmap, SlipBoundingBox.X[j], SlipBoundingBox.Y[k], SlipBoundingBox.WIDTH, SlipBoundingBox.HEIGHT);
//Filename formation originalPdfName_generatePdfName_pdfPageIndex_x_y.extension
File slip = new File(
getExternalFilesDir("slips")
+ "/"
+ finalOriginalPdfName
+ "_"
+ finalGeneratedPdfName
+ "_"
+ finalI +
"_"
+ SlipBoundingBox.X[j]
+ "_"
+ SlipBoundingBox.Y[k]
+ "_.jpg");
try (FileOutputStream out1 = new FileOutputStream(slip)) {
slipBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out1);
} catch (IOException e) {
e.printStackTrace();
}
slipBitmap.recycle();
}
}
pageBitmap.recycle();
pd.setMessage("Processed " + counter[0] + " of " + totalPage + " pages");
counter[0]++;
};
Future<?> future = executor.submit(runnable);
Log.d(TAG, "processPdf: " + future.isDone());
futureList.add(future);
}
//Todo close pdfrender on all page processed
//pdfRenderer.close();
} catch (Exception e) {
e.printStackTrace();
}