java 多进程写一个文件_java高并发多线程及多进程同时写入文件研究
测试&思考:
环境:windows 七、linux centos 6.三、java8html
java多线程同时写一个文件
java高并发环境下多线程同时写入一个文件时,
经过 FileLock 加锁,能够控制对文件的并发操做。同一个JVM,能够共享部份内存java
第一种状况是:一个线程A有对文件加锁,另外一个线程B没对文件加锁
在windows7环境下:(持有锁的能够写文件成功)。
持有锁的线程A会有对文件的操做权限,没加锁的线程B没有对文件的操做权限,会报错退出,以下:linux
java.io.IOException: 另外一个程序已锁定文件的一部分,进程没法访问。
在linux centos 6.3环境下:(均可以写文件成功,表现为数据交叉写入)
互不影响,线程A和B都有对文件的操做权限web
第二种状况两个线程都有加锁
在windows7环境和linux centos 6.3环境下表现同样:(持有锁的能够写文件成功)
一个线程A竞争到锁,会有对文件的操做权限,另外一个线程B没有竞争到锁,没有对文件的操做权限,会报错退出,而不是发生阻塞。以下:shell
java.nio.channels.OverlappingFileLockException
在高并的这种生产状况下,须要捕获这个异常,并处理,以下:windows
while (true) {
try {
flout = fcout.tryLock();
break;
} catch (Exception e) {
//计数等其余操做...
sleep(1000);
}
}
多进程同时写一个文件
若是同为java进程,则是不一样的JVM。不能够共享内存centos
若是同为java进程,一个进程A有对文件加锁,另外一个进程B没对文件加锁
在windows7环境下:(持有锁的能够写文件成功)。
持有锁的进程 A会有对文件的操做权限,没加锁的进程 B没有对文件的操做权限,会报错退出,以下:服务器
java.io.IOException: 另外一个程序已锁定文件的一部分,进程没法访问。
在linux centos 6.3环境下:(均可以写文件成功,表现为数据交叉写入)
互不影响,进程A和B都有对文件的操做权限多线程
若是同为java进程,两个进程都加锁
在windows7环境和linux centos 6.3环境下表现同样:
谁先得到锁,谁先得到对文件的操做权限,另外一个进程则会等待第一个进程处理完成,才会得到锁,再对文件进行处理。在这里是发生阻塞,而不是抛出异常(注意与多线程加锁的区别)。
由此能够证实:针对对多进程同时操做同一个文件,在这里应该是底层JVM层面或者本地方法接口库对这个文件进行了加锁。并发
一个为java进程,另外一个为非Java进程
此处操做全在服务器centos6.3上测试,非Java进程为简单的 shell 进程,例如:
for((i=1;i<10;i++));do echo 333 >> tmp.txt;sleep 1; done
java进程无锁的状况
互不影响,java进程和非java进程都有对文件的操做权限
java进程无锁的状况
互不影响,java进程和非java进程都有对文件的操做权限
总结
因而可知,在java高并发(不管是多线程仍是多进程)同时操做文件时。
若是没有文件顺序的限制,能够不加锁,在这里有操做系统为咱们兜底(这里有风险,是否是全部的操做系统都为咱们兜底呢)不会产生脏数据;
若是有文件顺序要求的限制,在这里不管是多线程仍是多进程(前提是Java服务),均可以获得很好的并发控制
若是能够接受加锁的开销和复杂度,只要遇到并发操做文件时均可以加锁。这样能够保证100%不会乱序,不用考虑是否操做系统会不会为咱们兜底了。
若是是使用FileLock try() 方法,同进程内的多线程访问, lock会直接报OverlappingFileLockException, 而不是一直阻塞。 若是是多进程, lock会一直阻塞,而不会包OverlappingFileLockException
这代表java提供的FileLock是面向整个虚拟机的,即进程级别的。合理利用FileLock,加上多线程的异常处理控制。就能够在多线程和多进程场景下实现对文件的高并发访问控制
FileLock 做用于java的进程级别,不管独占锁、共享锁都是针对不一样的进程,线程之间不适用。
测试代码
package com.dxm.etl.test;
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class TestFileLock {
public static void main(String args[]) throws Exception {
System.out.println(Thread.currentThread().getName());
// new ThreadWriteFileWithoutLock("111").start();
// Thread.sleep(1000);
new ThreadWriteFileWithLock("222").start();
}
private static class ThreadWriteFileWithLock extends Thread {
private String threadName;
public ThreadWriteFileWithLock(String threadName) {
this.threadName = threadName;
}
public void run() {
long t1 = System.currentTimeMillis();
File file = new File("tmp.txt");
FileOutputStream output = null;
BufferedWriter br = null;
FileChannel fileChannel = null;
try {
output = new FileOutputStream(file, true);
br = new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));
//对该文件加锁
fileChannel = output.getChannel();
FileLock fileLock = null;
fileLock = fileChannel.lock(0,Long.MAX_VALUE,false);
System.out.println(fileLock);
System.out.println(fileLock.isShared());
//非阻塞
/*while (true) {
try {
flout = fcout.tryLock();
break;
} catch (Exception e) {
System.out.println("有其余线程正在操做该文件,当前线程休眠1000毫秒");
sleep(1000);
}
}*/
for (int i = 1; i <= 10; i++) {
sleep(1000);
br.write(threadName+"\n");
br.flush();
}
fileLock.release();
} catch (Exception e) {
e.printStackTrace();
System.out.println(threadName +" err");
} finally {
try {
br.close();
fileChannel.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(threadName + "有锁,写文件共花了" + (System.currentTimeMillis() - t1) + "ms");
}
}
public static class ThreadWriteFileWithoutLock extends Thread {
private String threadName;
public ThreadWriteFileWithoutLock(String threadName) {
this.threadName = threadName;
}
public void run() {
long t1 = System.currentTimeMillis();
File file = new File("tmp.txt");
FileOutputStream output = null;
BufferedWriter br = null;
try {
output = new FileOutputStream(file, true);
br = new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));
for (int i = 1; i <= 10; i++) {
sleep(1000);
br.write(threadName+"\n");
br.flush();
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(threadName +" err");
} finally {
try {
br.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(threadName + "无锁,写文件共花了" + (System.currentTimeMillis() - t1) + "ms");
}
}
}
java 多进程写一个文件_java高并发多线程及多进程同时写入文件研究相关推荐
- java高并发多线程及多进程同时写入文件研究
文章目录 测试&思考: java多线程同时写一个文件 第一种情况是:一个线程A有对文件加锁,另一个线程B没对文件加锁 在windows7环境下:(持有锁的可以写文件成功). 在linux ce ...
- java 秒杀 源码 下载_java高并发秒杀系统3-4节秒杀功能实现.mp4
本Java商城秒杀系统视频教程目录如下: java高并发秒杀系统1-1节java高并发商城秒杀优化学习指引.mp4 java高并发秒杀系统1-2节项目环境搭建(Eclipse)-节.mp4 ja ...
- java商品详情页设计_java高并发秒杀系统3-2节商品详情页上.mp4
本Java商城秒杀系统视频教程目录如下: java高并发秒杀系统1-1节java高并发商城秒杀优化学习指引.mp4 java高并发秒杀系统1-2节项目环境搭建(Eclipse)-节.mp4 ja ...
- JAVA秒杀mysql层实现_Java高并发秒杀API之web层
第1章 设计Restful接口 1.1前端交互流程设计 1.2 学习Restful接口设计 什么是Restful?它就是一种优雅的URI表述方式,用来设计我们资源的访问URL.通过这个URL的设计,我 ...
- 用java程序写一个闹钟_java 使用swing制作一个小闹钟,包含以下功能:
展开全部 import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Font; import java.awt ...
- java支付宝支付_Java 高并发环境下的性能优化,揭秘支付宝技术内幕
前言 高并发经常会发生在有大活跃用户量,用户高聚集的业务场景中,如:秒杀活动,定时领取红包等. 为了让业务可以流畅的运行并且给用户一个好的交互体验,我们需要根据业务场景预估达到的并发量等因素,来设计适 ...
- java 高并发第三阶段实战_Java 高并发第三阶段实战---Java并发包深入解析与使用详解...
第三阶段的课程主要围绕着Java并发包的使用,展开详细的介绍,主要内容有1.原子包源码剖析,2.并发包工具类详细介绍,3.线程服务以及Future和callable等详细介绍,4.高并发容器和阻塞容器 ...
- Java IO练习--在程序中写一个“HelloJavaWorld你好世界“输出到操作系统文件Hello.txt文件中
package com.kj.test;import cn.hutool.core.io.IoUtil;import java.io.File; import java.io.FileOutputSt ...
- java 写一个HelloJavaWorld你好世界输出到操作系统文件Hello.txt文件中
package com.beiwo.homework;import java.io.File; import java.io.FileOutputStream; import java.io.IOEx ...
最新文章
- linux计划任务怎么做,做linux计划任务的步骤
- MySQL性能优化的21条最佳经验【转】
- 梯度下降法和随机梯度下降法
- 怎样成为一名更优秀的程序员?我总结出 7 条建议,希望对你们有帮助!
- java 是否继续_Java异常被抛出或被捕获之后,代码是否继续执行的问题
- Android自定义控件学习(三)----- 自定义视图组件
- AndroidTv开发中常用的adb命令
- 国企招聘 | NLP、语音和CV等算法岗位招聘实习生和应届全职生
- (收藏)C# .NET开发工具
- sendcloud历险记
- 右键 git找不到应用程序
- 用余弦算法做相似度匹配
- 车船税业务知识--天津(三)
- Docker(容器) 部署安装
- MATLAB中用李沙育图形分析光栅尺sincos信号正交性
- mysql的字符串等于函数吗_MySQL函数的字符串函数
- aso是做什么的_ASOer的目标
- 论坛报名 | 群体智能
- K8S 常见面试题总结
- 外包干了2年,彻底废了...
热门文章
- 在Windows Server 2008上创建 简单卷
- 广告贴——希望大家有空能够参加11月27日的《葵花宝典——WPF自学手册》签名售书活动...
- [BZOJ2716/2648][Violet 3]天使玩偶/SJY摆棋子[KDtree]
- web 埋点实现原理了解一下
- JAVA-JSP内置对象之out对象进行页面输出
- 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #3 如何编写内核模块
- PHP锁,分钟级别锁
- 并发学习笔记 (5)
- mysql传参数 和 区别_mybatis中#{}和${}传参方式的区别
- ip pim spare 源树 和 共享树_iPhone通过内置应用与电脑传输共享文件指南