運行線程package com.HL.DigestThread; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.swing.filechooser.FileNameExtensionFilter; import javax.xml.bind.DatatypeConverter; import javax.xml.bind.DatatypeConverterInterface; public class DigestThread extends Thread{ private String fileName; public DigestThread(String fileName){ this.fileName = fileName; } @Override public void run() { // TODO Auto-generated method stub try { FileInputStream inputStream = new FileInputStream(fileName); try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); DigestInputStream digestInputStream = new DigestInputStream(inputStream, messageDigest); try { while(digestInputStream.read() != -1); digestInputStream.close(); byte[]digest = messageDigest.digest(); StringBuilder result = new StringBuilder(fileName); result.append(":"); result.append(DatatypeConverter.printHexBinary(digest)); System.out.println(result); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } super.run(); } public static void main(String[] args) { for(String filename :args){ Thread t = new DigestThread(filename); t.start(); } } }main()方法從命令行中讀取文件名,針對每個文件名啓動一個新的DigestThread。
package com.HL.DigestThread;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.xml.bind.DatatypeConverter;
import javax.xml.bind.DatatypeConverterInterface;
public class DigestThreadRunnable implements Runnable{
private String fileName;
public DigestThreadRunnable(String fileName){
this.fileName = fileName;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
FileInputStream inputStream = new FileInputStream(fileName);
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
DigestInputStream digestInputStream = new DigestInputStream(inputStream, messageDigest);
try {
while(digestInputStream.read() != -1);
digestInputStream.close();
byte[]digest = messageDigest.digest();
StringBuilder result = new StringBuilder(fileName);
result.append(":");
result.append(DatatypeConverter.printHexBinary(digest));
System.out.println(result);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.run();
}
public static void main(String[] args) {
for(String filename :args){
DigestThreadRunnable dr = new DigestThreadRunnable(filename);
Thread thread = new Thread(dr);
thread.start();
}
}
}
public byte[] getDigest() {
return digest;
}
在主程序中使用存取方法取得線程輸出
package com.HL.DigestThread;
import javax.xml.bind.DatatypeConverter;
public class ReturnDigestTest {
public static void main(String[] args) {
for(String fileName : args){
DigestThread dt = new DigestThread(fileName);
dt.start();
//顯示結果
StringBuilder result = new StringBuilder(fileName);
result.append(":");
byte[]digest = dt.getDigest();
result.append(DatatypeConverter.printHexBinary(digest));
System.out.println(result);
}
}
}
但這樣做是存在問題的,我們可能得不到正確的輸出。因爲dt.start()啓動的計算可能在dt.getDigest()之前還沒有結束,也可能結束了,主線程是不會等子線程的。如果還沒有結束,dt.getDigest()則會返回null,此時訪問digest會拋出異常。
package com.HL.callableTest;
import java.util.concurrent.Callable;
public class FindMaxTask implements Callable<Integer>{
private int[]data;
private int start;
private int end;
public FindMaxTask(int[]data,int start,int end ) {
// TODO Auto-generated constructor stub
this.data = data;
this.start = start;
this.end = end;
}
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
int max = Integer.MIN_VALUE;
for(int i = start; i < end; i++){
if(data[i] > max) max = data[i];
}
return max;
}
}
package com.HL.callableTest;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadMaxFinder {
public static int max(int[]data) throws InterruptedException, ExecutionException {
if(data.length == 1)return data[0];
FindMaxTask task1 = new FindMaxTask(data, 0, data.length/2);
FindMaxTask task2 = new FindMaxTask(data, data.length/2, data.length);
//創建兩個線程
ExecutorService service = Executors.newFixedThreadPool(2);
Future<Integer> future1 = service.submit(task1);
Future<Integer> future2 = service.submit(task2);
return Math.max(future1.get(), future2.get());
}
public static void main(String[] args) {
try {
System.out.println(String.valueOf(max(new int[]{12,5,16})));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}