java多執行緒批量讀取檔案(一)
新公司入職一個多月了,至今沒有事情可以做,十來個新同事都一樣抓狂,所以大家都自己學習一些新東西,我最近在看zookeeper,感覺蠻不錯的,和微服務的zuul以及eureka功能類似,只是程式碼複雜了一些。而今天,我所要說的是java多執行緒讀取檔案的兩個例子;
例子1:java多執行緒批量讀取檔案
package face.thread.ReadFile;
/**
* 多執行緒讀、寫檔案
*
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CompareTest3 {
public static void main(String args[]) {
long millis1 = System.currentTimeMillis();
System.out.println(millis1);
Read3 read = new Read3(millis1);
ExecutorService service = Executors.newFixedThreadPool(5);
for(int i = 1; i <= 3; i++){
service.execute(new Thread(read, "執行緒" + i));
}
}
}
class Read3 implements Runnable {
Object o = new Object();
List<File> filePathsList = new ArrayList<File>();
int index = 0;
private long millis ;
public Read3(long millis1 ) {
this.millis = millis1;
File f = new File("d:" + File.separator + "gc2");
getFileList(f);
}
private void getFileList(File f) {
File[] filePaths = f.listFiles();
for (File s : filePaths) {
if (s.isDirectory()) {
getFileList(s);
} else {
if (-1 != s.getName().lastIndexOf(".txt")) {
filePathsList.add(s);
}
}
}
}
public void run() {
File file = null;
File f2 = null;
while (index < filePathsList.size()) {
//此處,保證了多執行緒不會交叉讀取檔案
//--1.1方法內的變數是執行緒安全的 //解釋:由於方法內的變數是私有的,本體訪問的同時別人訪問不了,所以是執行緒安全的。 //--1.2例項變數是非執行緒安全的 //解釋:由於例項變數可以由多個執行緒訪問,當本體操作變數過程中,別人也可以搶佔資源操作變數,使資料不同步了,所以是非執行緒安全的。
synchronized (o) {
if (index > filePathsList.size()) {
return;
}
file = filePathsList.get(index);
index++;
//System.out.println("內部index: " + index);
}
// System.out.println("檔案: " + file.getName());
FileReader fr = null;
BufferedReader br = null;
StringBuffer sb = new StringBuffer();
FileWriter fw = null;
BufferedWriter bw = null;
f2 = new File("d:" + File.separator + "gc3" + File.separator + file.getName());
try {
fr = new FileReader(file);
br = new BufferedReader(fr);
fw = new FileWriter(f2);
bw = new BufferedWriter(fw);
String data = "";
while((data = br.readLine()) != null){
// sb.append(data + "\r");
bw.write(data + "\r");
}
bw.write("---------------" + Thread.currentThread().getName()+"---------------");
System.out.println(Thread.currentThread().getName() + " : " + file.getName());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
bw.close();
br.close();
/*long millis2 = System.currentTimeMillis();
System.out.println(millis2);
System.out.println(millis2 - millis); //大約1-2ms*/
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
例子2:同樣的讀取檔案,改為單執行緒讀取
package face.thread.ReadFile;
/**
* 單執行緒讀、寫檔案
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CompareTest4 {
public static void main(String args[]) {
final long millis1 = System.currentTimeMillis();
final CyclicBarrier cb = new CyclicBarrier(1,new Runnable(){
public void run() {
long millis2 = System.currentTimeMillis();
System.out.println(millis2);
System.out.println(millis2 - millis1); //大約1-2ms
}
});
Read4 read = new Read4(cb);
ExecutorService service = Executors.newFixedThreadPool(1);
for(int i = 1; i <= 1; i++){
service.execute(new Thread(read, "執行緒" + i));
}
}
}
class Read4 implements Runnable {
Object o = new Object();
List<File> filePathsList = new ArrayList<File>();
int index = 0;
CyclicBarrier cb2;
public Read4(CyclicBarrier cb) {
this.cb2 = cb;
File f = new File("d:" + File.separator + "gc2");
getFileList(f);
}
private void getFileList(File f) {
File[] filePaths = f.listFiles();
for (File s : filePaths) {
if (s.isDirectory()) {
getFileList(s);
} else {
if (-1 != s.getName().lastIndexOf(".txt")) {
filePathsList.add(s);
}
}
}
}
public void run() {
File file = null;
File f2 = null;
while (index < filePathsList.size()) {
synchronized (o) {
if (index > filePathsList.size()) {
return;
}
file = filePathsList.get(index);
index++;
//System.out.println("內部index: " + index);
}
// System.out.println("檔案: " + file.getName());
FileReader fr = null;
BufferedReader br = null;
StringBuffer sb = new StringBuffer();
FileWriter fw = null;
BufferedWriter bw = null;
f2 = new File("d:" + File.separator + "gc3" + File.separator + file.getName());
try {
fr = new FileReader(file);
br = new BufferedReader(fr);
fw = new FileWriter(f2);
bw = new BufferedWriter(fw);
String data = "";
while((data = br.readLine()) != null){
// sb.append(data + "\r");
bw.write(data + "\r");
}
bw.write("---------------" + Thread.currentThread().getName()+"---------------");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
bw.close();
br.close();
try {
cb2.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
兩個例子中,列印的時間即代表執行緒讀取每個程式碼的時間,效能對比一看就能體現出來,只是個小Demo,望大神勿噴!