Javaマルチスレッド書き込み同じファイル実装
4655 ワード
最近のプロジェクトでは、Webサイトから大量のデータをキャプチャする必要があります.マルチスレッド技術を採用しており、各スレッドがキャプチャしたデータを1つのファイルに保存し、大量のメモリを消費しないようにする必要があります.
アイデア:複数のアクセススレッドは、ファイルに書き込む必要があるデータを1つのキューに保存し、キューからデータを取り出してファイルに書き込む専門の書き込みスレッドです.
WriterQueue.JAva出力するデータキューの格納
WriteTask_New.JAvaシミュレーションによるデータ生成のスレッドクラス
OutputTask.JAvaはデータをファイルに書き込む責任を負います
テストクラス
アイデア:複数のアクセススレッドは、ファイルに書き込む必要があるデータを1つのキューに保存し、キューからデータを取り出してファイルに書き込む専門の書き込みスレッドです.
WriterQueue.JAva出力するデータキューの格納
package com.yulore.write;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class WriterQueue {
private static final int MAX_QUEUE_SIZE = 5000;
private LinkedList<String> queue = new LinkedList<String>();
private Lock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();
private static WriterQueue manager = new WriterQueue();
private WriterQueue(){
}
public static WriterQueue getQueue(){
return manager;
}
public void put(String phone){
lock.lock();
try {
while (queue.size() == MAX_QUEUE_SIZE) {
System.out.println("warning: data queue is full!");
notFull.await();
}
queue.addFirst(phone);
notEmpty.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
lock.unlock();
}
}
public LinkedList<String> takeAll(){
LinkedList<String> retVal = new LinkedList<String>();
lock.lock();
try {
while (queue.size() == 0) {
System.out.println("warning: data queue is empty!");
notEmpty.await();
}
retVal.addAll(queue);
// for(String str : queue){
// retVal.add(str);
// }
//
queue.clear();
notFull.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
lock.unlock();
}
return retVal;
}
}
WriteTask_New.JAvaシミュレーションによるデータ生成のスレッドクラス
package com.yulore.write;
public class WriteTask_New implements Runnable {
@Override
public void run() {
for(int i=0;i<20;i++){
// try {
// sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
WriterQueue.getQueue().put("for:"+i+" thread:"+Thread.currentThread().getName());
}
}
private void sleep(int millis) throws InterruptedException {
Thread.sleep(millis);
}
}
OutputTask.JAvaはデータをファイルに書き込む責任を負います
package com.yulore.write;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
public class OutputTask implements Runnable {
private String fileName;
public OutputTask(String fileName) {
this.fileName = fileName;
}
@Override
public void run() {
while(true){
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LinkedList<String> list = WriterQueue.getQueue().takeAll();
write2Disk(list);
list = null;
}
}
private void write2Disk(LinkedList<String> list) {
if(list==null ||list.size()==0){
System.out.println("no data...");
return;
}
System.out.println(" "+fileName);
String path = "D:/fbb/myWorkSpace_DW07/";
File outputFile = new File(path+fileName);
if(outputFile==null ||!outputFile.exists()){
try {
outputFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileOutputStream out = null;
OutputStreamWriter writer = null;
BufferedWriter bw = null;
try {
out = new FileOutputStream(outputFile, true);
writer = new OutputStreamWriter(out);
bw = new BufferedWriter(writer);
for(String content : list){
bw.write(content);
bw.newLine();
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(bw!=null)
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void sleep(int millis) throws InterruptedException {
Thread.sleep(millis);
}
}
テストクラス
package com.yulore.write;
public class TestWrite {
/**
* @param args
*/
public static void main(String[] args) {
// test();
test02();
}
private static void test02() {
WriteTask_New write = new WriteTask_New();
for(int i=0;i<4;i++){
new Thread(write).start();
}
OutputTask output = new OutputTask("abc.txt");
new Thread(output).start();
}
private static void test() {
WriteTask write = new WriteTask("abc.txt");
for(int i=0;i<5;i++){
new Thread(write).start();
}
}
}