【发布时间】:2018-04-25 11:14:17
【问题描述】:
此程序按顺序获取输入文件,但所有任务使用单个内核并行执行。所有任务的执行时间都比顺序执行时间长。我想通过并行执行任务来减少使用多个内核的执行时间。我怎样才能做到这一点?如何在这个程序中使用多核?我想使用至少两个核心。
package TestParallel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
/**
*
* @author Sohel Rana
*/
public class Executor {
public void encrypt(File fname) throws Exception {
System.out.println("Encryption Started : " + System.currentTimeMillis() + " File Name : " + fname);
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); //using AES-256
SecretKey key = keyGen.generateKey(); //generating key
// System.out.println("Key = " + bytesToHex(key.getEncoded()));
Cipher aesCipher = Cipher.getInstance("AES"); //getting cipher for AES
aesCipher.init(Cipher.ENCRYPT_MODE, key); //initializing cipher for encryption with key
//creating file output stream to write to file
try (FileOutputStream fos = new FileOutputStream(fname + ".aes")) {
//creating object output stream to write objects to file
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(key); //saving key to file for use during decryption
//creating file input stream to read contents for encryption
try (FileInputStream fis = new FileInputStream(fname)) {
//creating cipher output stream to write encrypted contents
try (CipherOutputStream cos = new CipherOutputStream(fos, aesCipher)) {
int read;
byte buf[] = new byte[4096];
while ((read = fis.read(buf)) != -1) //reading from file
{
cos.write(buf, 0, read); //encrypting and writing to file
}
}
}
System.out.print("\nComplete Time = " + System.currentTimeMillis());
System.out.println(" \tand file task complete :" + fname);
// fname.delete();
}
}
public static void main(final String[] args) throws InterruptedException {
// final ExecutorService pool = Executors.newFixedThreadPool(4);
int cores = Runtime.getRuntime().availableProcessors();
System.out.println("Available processor cores is " + cores);
File file1 = new File("C:\\Users\\Sohel Rana\\Desktop\\test\\Khushnuma Official Video HD - Suyyash Rai & Kishwer Merchant_HD.mp4");
File file2 = new File("C:\\Users\\Sohel Rana\\Desktop\\test\\EK MULAQAT - Sonali Cable HD.mp4");
File file3 = new File("C:\\Users\\Sohel Rana\\Desktop\\test\\Java Cryptography Tutorials 1 AES Encryption and Decryption using Java.mp4");
File file4 = new File("C:\\Users\\Sohel Rana\\Desktop\\test\\01. Nath Nath.MP4");
Executor ex = new Executor();
final ExecutorService executor = Executors.newFixedThreadPool(cores);
long startTime = System.currentTimeMillis();
for (File f : new File[]{file1, file2, file3, file4}) {
startTime = System.currentTimeMillis();
executor.execute(() -> {
try {
ex.encrypt(f);
//System.out.println(f);
} catch (Exception ex1) {
Logger.getLogger(Executor.class.getName()).log(Level.SEVERE, null, ex1);
}
});
}
executor.shutdown();
if (executor.awaitTermination(1, TimeUnit.DAYS)) {
} else {
executor.shutdownNow();
}
long endTime = System.currentTimeMillis();
System.out.println("\nParalle Execution Time : " + (endTime - startTime)
+ " milliseconds.");
}
}
【问题讨论】:
-
你的代码有什么问题?
-
首先取决于你的硬件,这段代码是为哪个硬件编译的?该硬件是否至少有 2 个内核?
-
你的意思是多线程。只需创建一个新线程
-
我的代码在单核上运行良好。我想使用两个内核快速运行。我可以从 cpu 获得最大响应。这意味着当运行代码时,cpu 性能将是 100%。怎么能这样?
-
分析您的代码以查看等待发生的位置...您在每个工作线程使用非常大的工作单元 - 即整个 mp4 文件,而每个工作人员通过读取 4kB 严重依赖 I/O当时......这是非常健谈的 I/O 访问,我的猜测(但在行动之前测量)是所有线程都花费大量时间等待 I/O。尝试当时读取 40kB 或 400kB,看看它会如何改变时间。您可以使用
Executors.workStealingPool(cores),但要获得好处,您的工作项必须比整个文件小得多(可能是缓冲区的大小)。
标签: java parallel-processing aes executorservice multicore