多线程向一个文件中写数据

专门处理文件的类------RandomAccessFile类 Java除了File类之外,还提供了专门处理文件的类,即RandomAccessFile(随机访问文件)类。该类是Java语言中功能最为丰富的文件访问类,它提供了众多的文件访问方法。RandomAccessFile类支持“随机访问”方式,这里“随机”是指可以跳转到文件的任意位置处读数据。在访问一个文件的时候,不必把文件从头读到尾,而是希望像访问一个数据库一样“随心所欲”地访问一个文件的某个部分,... 阅读详情

最近被问到Log4j如何通过多个线程向一个文件中写入数据,当时没有一点头绪, 因为用过windows记事本的小伙伴都知道,当一个记事本文件被同时打开多次,并且每个都修改,那么只会保留第一次打开的内容,这就是互斥锁的机制吧。 

具体场景:三个线程分别读取三个文件a,b,c 并向d文件中写入

现在想起来两个方案给小伙伴分享一下:

第一种(不可行)使用IO流复用,就是多个线程共用一个IO流

       出现问题:

              1.部分文件内容无法保存。

              2.影响其它线程使用文件

第二种方案:

思路:既然不能同时读写,那么就一个或多个线程读取文件,然后单独的一个或多个线程写文件。

比如 创建三个线程r1,r2,r3分别读取a,b,c  创建一个线程w1将内容写入到 d. 那么读写操作就可以同步进行,也不需要IO复用了,只需要创建一个缓冲区即可。



不多说了,上代码(因为需要代码尽量清晰,省略所有io.close())



/**
 * 从abc三个文件中向d中写
 * 多个线程向内存数组中读,读完之后,由单独的一个线程写入到文件中
 */
public class Main042{
	//创建堵塞队列,用于读线程的数据存放
	public static BlockingQueue<byte[]> queue = new ArrayBlockingQueue<>(1024*1024);
	//创建 CountDownLatch,标记读线程的状态(是否读取完成)。
	public static CountDownLatch count =new CountDownLatch(3);
	public static void main(String[] args){
		Read r1= new Read("d:/a.txt",queue,count);
		Read r2= new Read("d:/b.txt",queue,count);
		Read r3= new Read("d:/c.txt",queue,count);
		Write w1 = new Write("d:/d.txt", queue, count);
		r1.start();
		r2.start();
		r3.start();
		w1.start();
	}
	
}

class Write extends Thread{
	private BlockingQueue<byte[]> buffer;
	private FileOutputStream fileOutputStream;
	private CountDownLatch count;
	public Write(String file,BlockingQueue<byte[]> buffer,CountDownLatch count) {
		this.buffer = buffer;
		this.count =count;
		try {
			this.fileOutputStream = new FileOutputStream(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	public void run(){
		boolean b =true;
		while(b) {
			try {
				fileOutputStream.write(buffer.take());
			} catch (Exception e) {
				e.printStackTrace();
			}
			if(buffer.isEmpty()&&count.getCount()==0) {
				//当缓冲区没有元素,并且 count为0,则说明读写完成
					b =false;
			}
		}
		
	}
}
//读线程
class Read extends Thread{
	private BlockingQueue<byte[]> buffer;
	private FileInputStream fileInputStream;
	private CountDownLatch count;
	private volatile int i=0;
	
	public Read(String readFileName, BlockingQueue<byte[]> buffer,CountDownLatch count) {
		this.count = count;
		this.buffer = buffer;
		try {
			this.fileInputStream = new FileInputStream(readFileName);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	public void run(){
		try {
			byte[] b = new byte[1024*10];
			while((i = fileInputStream.read(b))>=0) {
					buffer.put(Arrays.copyOf(b, i));
				}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			count.countDown();//读线程结束,count--;
		}
	}
}





用线程池实现多线程同一个文件写入数据 最近接到一项工作,是要计算某个省的所有县,两两之间的距离。这个排列组合大约有2万条记录。我采取的是百度地图API来查询两个县之间的距离。由于访问百度地图API请求数据,需要一定的时间,所以考虑使用java的线程池创建多线程来完成这一项工作,一边去baidu地图查询结果,一边向CSV文件写入数据。 代码如下: //用队列存放每一个线程执行的结果值。 Queue result  = new L 阅读详情

相关推荐

QT多线程Qthread读同一个文件问题

两个线程可以同时打开一个文件,并且同时和读都是可以的,都没有限制但是Qthread读

AIcar_lrm的博客 2562

多个线程同时一个文件

class Program { #region 私有字段 // 文件名 static readonly string FileName = "demoFile.data"; // 要写入文件的 9 个字节 static readonly byte[] orgBuffer = { 0x0C, 0x10, 0x02, 0xE3, 0x71, 0xA2, ...

Clement 2767

多线程文件 加锁

 两个线程同时对一个文件的操作:其中一个线程对文件进行操作,即接受外部的数据,同时另外一个线程对文件进行读的操作,这样如何实现?  定义一个全局         HANDLE   hFileLock;    在程序开始时初始化         hFileLock   =   CreateMutex(NULL,   false,   NULL);    程序中这样处理:    文件

xyxwangkai的专栏 2005

对同一文件进行多线程写入

 考多线程文件(三种方法)以下转贴using   System;     using   System.Threading;     using   System.IO;         namespace   CopyTest     {         //FileBuffer用来存放和取出缓冲区变量     public   class   FileBuffer{     private

编程的艺术世界 - Bruce Lee 3414

java多线程 同时一个文件

我整理的一些关于【数据】的项目学习资料(附讲解~~)和大家一起分享、学习一下:https://d.51cto.com/eDOcp1Java多线程同时一个文件 在软件开发中,多线程编程是一个重要的主题,尤其在需要提升程序性能和响应能力的场景中更是如此。Java作为一种广泛使用的编程语言,提供了强大的多线程支持。然而,当多...

weixin_36246576的博客 850

Google多线程面试题: 4个线程向4个文件写入数据, 每个线程只能一个

By Long Luo个人博客链接最近在学习Java多线程时,遇到了一个下面的笔试题,题目如下: 编一个程序,程序会启动4个线程,向4个文件A,B,C,D里写入数据,每个线程只能一个值。 线程A:只A 线程B:只B 线程C:只C 线程D:只D 4个文件A,B,C,D。 程序运行起来,4个文件写入结果如下: A:ABCDABCD...

TCP/IP协议栈学习ing 4853

Google多线程面试题: 4个线程向4个文件写入数据, 每个线程只能一个值(待更新)

一个程序,程序会启动4个线程,向4个文件A,B,C,D里写入数据,每个线程只能一个值。 线程A:只A 线程B:只B 线程C:只C 线程D:只D 4个文件A,B,C,D。 程序运行起来,4个文件写入结果如下: A:ABCDABCD... B:BCDABCDA... C:CDABCDAB... D:D

blog of city 2084

java 文件 保证线程_java多线程文件示例

package com.ysh.file;import java.util.ArrayList;import java.util.LinkedList;import java.util.List;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.co...

weixin_28685483的博客 166

使用CountDownLatch模拟多线程文件,所有文件线程完后,主线程读取文件

使用CountDownLatch模拟多线程文件,所有文件线程完后,主线程读取文件 package juc; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.time.LocalDateTime; import java.time.for

Mars的专栏 465

java实现多线程读,单线程

多线程读,单线程excel 通过工厂模式,队列实现多线程读取(可以是文件,也可以是数据库),单线程向excel文件;实现了一个线程出现问题其他线程同步中断。该实现逻辑的同时可以防止oom

oovooo的博客 455

java 同时读文件_java 对同一个文件的同时读

/////对文件操作public class fileRW {/*** @param args* @throws IOException*/public static void main(String[] args) throws IOException {// TODO Auto-generated method stubnew ThreadWrite().start();//new T...

weixin_34551573的博客 866

读者者问题(读者优先)C语言

读者者问题(读者优先) C语言 linux上可运行

weixin_64579808的博客 1104

疑问:sqlite多线程操作效率问题

sqlite多线程操作效率问题 记一次实际项目中sqlite多线程操作效率的问题 场景:两个db文件,每个db文件有10张表,每张表的结构都一样,各有200条纪录 需求:需要在两个db文件中各建一张新表newtable(结构和那10张表一样包括索引和其他),然后将另外10张表中的数据也就是2000条记录插入到newtable中,再删掉10张表(执行10个drop table xx;)。也就是说针对一个db,我需要执行两个操作,insert into和drop table。 我的代码实现: 方式一 多线

梦殇王子的博客 536

linux文件加锁及解锁

当有多个工作线程要同时对一个文件进行操作时,如果不对该文件进行加锁就可能会因误操作而引起一系列的问题。 解决这个问题有多种方法。我们这里考虑使用文件锁来对文件进行保护,因为这个方法简单易行。具体方法是使用Flock函数进行加锁: if((flock(fd, LOCK_EX | LOCK_NB))< 0) { std::cout<

wenbie123的专栏 1万+

作业:将一个文件中的数据打印到终端上,类似cat一个文件

A线程读取文件中的数据 B线程将A线程读取到的数据打印到终端上 文件打印完毕后,结束进程。

m0_74849777的博客 178

c语言多线程实例

#include "stdafx.h" #include<windows.h> #include <stdio.h> HANDLE hFile; //定义临界区 CRITICAL_SECTION cs; DWORD WINAPI Thread(LPVOID lpParam) { //得到线程的编号 int n = (int)lpParam; DWORD dvWrite; for (int i = 0; i < 10000; i++){ //进入临界区 En..

reg183的专栏 1499
上一篇: Spring Boot1.52 Spring Security Spring Data Jpa 整合
下一篇: Shell编程<一>
Lmdestiny
博客等级 码龄11年 0粉丝 8原创
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值