测试&思考:

环境: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高并发多线程及多进程同时写入文件研究相关推荐

  1. java高并发多线程及多进程同时写入文件研究

    文章目录 测试&思考: java多线程同时写一个文件 第一种情况是:一个线程A有对文件加锁,另一个线程B没对文件加锁 在windows7环境下:(持有锁的可以写文件成功). 在linux ce ...

  2. java 秒杀 源码 下载_java高并发秒杀系统3-4节秒杀功能实现.mp4

    本Java商城秒杀系统视频教程目录如下:    java高并发秒杀系统1-1节java高并发商城秒杀优化学习指引.mp4 java高并发秒杀系统1-2节项目环境搭建(Eclipse)-节.mp4 ja ...

  3. java商品详情页设计_java高并发秒杀系统3-2节商品详情页上.mp4

    本Java商城秒杀系统视频教程目录如下:    java高并发秒杀系统1-1节java高并发商城秒杀优化学习指引.mp4 java高并发秒杀系统1-2节项目环境搭建(Eclipse)-节.mp4 ja ...

  4. JAVA秒杀mysql层实现_Java高并发秒杀API之web层

    第1章 设计Restful接口 1.1前端交互流程设计 1.2 学习Restful接口设计 什么是Restful?它就是一种优雅的URI表述方式,用来设计我们资源的访问URL.通过这个URL的设计,我 ...

  5. 用java程序写一个闹钟_java 使用swing制作一个小闹钟,包含以下功能:

    展开全部 import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Font; import java.awt ...

  6. java支付宝支付_Java 高并发环境下的性能优化,揭秘支付宝技术内幕

    前言 高并发经常会发生在有大活跃用户量,用户高聚集的业务场景中,如:秒杀活动,定时领取红包等. 为了让业务可以流畅的运行并且给用户一个好的交互体验,我们需要根据业务场景预估达到的并发量等因素,来设计适 ...

  7. java 高并发第三阶段实战_Java 高并发第三阶段实战---Java并发包深入解析与使用详解...

    第三阶段的课程主要围绕着Java并发包的使用,展开详细的介绍,主要内容有1.原子包源码剖析,2.并发包工具类详细介绍,3.线程服务以及Future和callable等详细介绍,4.高并发容器和阻塞容器 ...

  8. Java IO练习--在程序中写一个“HelloJavaWorld你好世界“输出到操作系统文件Hello.txt文件中

    package com.kj.test;import cn.hutool.core.io.IoUtil;import java.io.File; import java.io.FileOutputSt ...

  9. java 写一个HelloJavaWorld你好世界输出到操作系统文件Hello.txt文件中

    package com.beiwo.homework;import java.io.File; import java.io.FileOutputStream; import java.io.IOEx ...

最新文章

  1. linux计划任务怎么做,做linux计划任务的步骤
  2. MySQL性能优化的21条最佳经验【转】
  3. 梯度下降法和随机梯度下降法
  4. 怎样成为一名更优秀的程序员?我总结出 7 条建议,希望对你们有帮助!
  5. java 是否继续_Java异常被抛出或被捕获之后,代码是否继续执行的问题
  6. Android自定义控件学习(三)----- 自定义视图组件
  7. AndroidTv开发中常用的adb命令
  8. 国企招聘 | NLP、语音和CV等算法岗位招聘实习生和应届全职生
  9. (收藏)C# .NET开发工具
  10. sendcloud历险记
  11. 右键 git找不到应用程序
  12. 用余弦算法做相似度匹配
  13. 车船税业务知识--天津(三)
  14. Docker(容器) 部署安装
  15. MATLAB中用李沙育图形分析光栅尺sincos信号正交性
  16. mysql的字符串等于函数吗_MySQL函数的字符串函数
  17. aso是做什么的_ASOer的目标
  18. 论坛报名 | 群体智能
  19. K8S 常见面试题总结
  20. 外包干了2年,彻底废了...

热门文章

  1. 在Windows Server 2008上创建 简单卷
  2. 广告贴——希望大家有空能够参加11月27日的《葵花宝典——WPF自学手册》签名售书活动...
  3. [BZOJ2716/2648][Violet 3]天使玩偶/SJY摆棋子[KDtree]
  4. web 埋点实现原理了解一下
  5. JAVA-JSP内置对象之out对象进行页面输出
  6. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #3 如何编写内核模块
  7. PHP锁,分钟级别锁
  8. 并发学习笔记 (5)
  9. mysql传参数 和 区别_mybatis中#{}和${}传参方式的区别
  10. ip pim spare 源树 和 共享树_iPhone通过内置应用与电脑传输共享文件指南