一、缘起

最近出现一个需求,大体要做的就是控制多线程同时操作一个文件。当时第一个反应是不要用synchronized,太low了,然后我就使用了读写锁ReentrantReadWriteLock,然后写完静下来和业务结合在一起分析一下,结果尴尬了。因为文件名可能是别的线程刚刚生成的带上了时间戳,线程A写orders_201904171130.xls文件,线程B写orders_201904171131.xls文件,这个时候实际上时不能阻塞的。Lock没办法像synchronized关键字一样,给定一把锁,锁住特定的对象。锁对象不同,则不阻塞

然后试着使用synchronized代码块,使用filename作为锁对象,初一看好像可以,但是经不住测试哇,测试的时候即使同一个文件名,还是不能阻塞,因为filename是属于拼接起来的,且还是局部变量,所以这个filename的string虽然在常量池中值是一样的,但是在堆里的对象地址是不一样的,所以synchronized肯定认为不是同一个对象锁,所以同一个文件名并没有阻塞

然后想起来使用RandomAccessFile和FileLock实现,但是我这种情况下是往远程服务器共享目录读写,File类是用不了的。所以他也用不了。

二、使用synchronized实现

如上述所说,文件名属于拼接的,虽然是指向同一个常量,但是String的堆地址变化了,所以采用intern()方法可以做到。api表示:一个与该字符串具有相同内容的字符串,但保证来自一个唯一字符串池。。它的返回值:一个字符串,内容与此字符串相同,但一定取自具有唯一字符串的池。

至于写文件的代码就不贴了,大致就是在写的部分使用synchronized代码块,对象锁直接使用intern()方法返回的filename

三、使用RandomAccessFile和FileLock相结合

附上RandomAccessFile和FileLock实现处理多人同时读写文件的参考连接:

https://blog.csdn.net/gxy3509394/article/details/7435993

java控制多线程同时写一个文件的更多相关文章

  1. 在java程序当中怎么获取一个文件的路径

    在java程序当中怎么获取一个文件的路径? * 当这个文件在类路径下的时候(在src/bin目录下的时候): String absolutePath = Thread.currentThread(). ...

  2. 使用Java的多线程和IO流写一个文件复制功能类

    创建一个复制功能类,继承Thread类,重写run()方法,把FileInputStream和FileOutputStream输入输出流写在run()方法内.示例代码如下: import java.i ...

  3. python利用socket写一个文件上传

    1.先将一张图片拖入‘文件上传’的目录下,利用socket把这张图片写到叫‘yuan’的文件中 2.代码: #模拟服务端 import subprocess import os import sock ...

  4. java中jar命令打包一个文件夹下的所有文件

    (1)首先,必须保证java的所有路径都设置好,在dos提示符下输入jar -help出现C:\Documents and Settings\dly>jar -help非法选项:h用法:jar ...

  5. ruby写一个文件内容相似性比较的代码

    1.相似度定义 我们定义,则,我们设,则,|C|=s,则相似度p=,p(0,1) 2.相似度检测算法设计 算法设计: 定义4个字符为一个字符串,将T1,T2分割成若干字符串,若剩余字符不足4个,则以空 ...

  6. Java控制多线程执行顺序

    package net.jasonjiang.thread; import java.io.IOException; public class ThreadTestNew { public stati ...

  7. php如何解决多线程同时读写一个文件的问题

    <?php header("content-type:text/html;charset=utf-8"); $fp = fopen("lock.txt", ...

  8. 键盘录入一个文件夹路径,统计该文件夹(包含子文件夹)中每种类型的文件及个数,注意:用文件类型(后缀名,不包含.(点),如:"java","txt")作为key, 用个数作为value,放入到map集合中,遍历map集合

    package cn.it.zuoye5; import java.io.File;import java.util.HashMap;import java.util.Iterator;import ...

  9. 简化日常工作之三:自己写一个CI脚手架

    程序员是诗人,应该写一些有思想意义的code,而不是每天重复造轮子,写一些低成本的业务逻辑. ---------------------------------一个脚本仔的心声 由于目前公司使用CI框 ...

随机推荐

  1. linux环境下vim创建java文件,并编译运行

    一.前提 安装Java 二.创建工作目录并编辑java文件 三.编译 四.运行

  2. jQuery 与 Ajax 的应用

    Ajax 全称为 "Asynchronous JavaScript and XML"(异步 JavaScript 和 XML ),它并不是指一种单一的技术,而是有机地利用了一系列交 ...

  3. java 枚举2

    package com.wsy.test; public enum Color { RED("红色",1),GREEN("绿色",2),BLUE("蓝 ...

  4. C# AddRange为数组添加多个元素的代码

    将代码过程中重要的代码片段做个收藏,下面代码段是关于C# AddRange为数组添加多个元素的代码,希望对小伙伴有所用处.ArrayList ab = new ArrayList();ab.Add(& ...

  5. 在线SQL

    有时候为了简单测试一下SQL语法,自己机器上没有安装,可使用在线的SQL环境. 我找到了两个: https://rextester.com/l/sql_server_online_compiler ( ...

  6. codeblocks(其它软件)修改后缀文件的打开默认方式

  7. grep废弃

    grep -inrw 字符串 .grep -i是忽略大小写的意思cat xxx|grep -i mem 会把文本里的MEM,meM.....等无关乎大小写的内容取出来grep -inrwgrep &q ...

  8. 【莫烦Pytorch】【P1】人工神经网络VS. 生物神经网络

    滴:转载引用请注明哦[握爪] https://www.cnblogs.com/zyrb/p/9700343.html 莫烦教程是一个免费的机器学习(不限于)的学习教程,幽默风俗的语言让我们这些刚刚起步 ...

  9. Eclipse MAT 安装及使用

    Eclipse MAT官方网页:https://www.eclipse.org/mat/downloads.php 一.MAT是什么? MAT(Memory Analyzer Tool),一个基于Ec ...

  10. 快速掌握Nginx(三) —— Nginx+Systemd托管netcore应用

    以前dotnet web应用程序开发完成后,我们都是使用IIS部署在Windows Server上,如今netcore技术发展迅速,因为其跨平台的特性,将dotnet web应用程序部署在更方便部署和 ...