热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java中RandomAccessFile的并发性

如何解决《Java中RandomAccessFile的并发性》经验,为你挑选了2个好方法。

我正在创建一个RandomAccessFile对象,以便通过多个线程写入文件(在SSD上).每个线程都尝试在文件中的特定位置写一个直接字节缓冲区,并确保线程写入的位置不会与另一个线程重叠:

file_.getChannel().write(buffer, position);

where file_的实例是RandomAccessFilebuffer直接字节缓冲区.

对于RandomAccessFile对象,由于我没有使用fallocate来分配文件,并且文件的长度在变化,这是否会利用底层媒体的并发性?

如果不是,在创建文件时如果没有调用fallocate,使用上述函数是否有任何意义?



1> Adonis..:

我用以下代码进行了一些测试:

   public class App {
    public static CountDownLatch latch;

    public static void main(String[] args) throws InterruptedException, IOException {
        File f = new File("test.txt");
        RandomAccessFile file = new RandomAccessFile("test.txt", "rw");
        latch = new CountDownLatch(5);
        for (int i = 0; i <5; i++) {
            Thread t = new Thread(new WritingThread(i, (long) i * 10, file.getChannel()));
            t.start();

        }
        latch.await();
        file.close();
        InputStream fileR = new FileInputStream("test.txt");
        byte[] bytes = IOUtils.toByteArray(fileR);
        for (int i = 0; i 

到目前为止我所看到的:

Windows 7(NTFS分区):线性运行(也就是一个线程写入,当它结束时,另一个线程运行)

Linux Parrot 4.8.15(ext4分区)(基于Debian的发行版),Linux内核4.8.0:线程在执行期间混合

再次如文档所述:

文件通道可供多个并发线程使用.可以在Channel接口指定的任何时间调用close方法.在任何给定时间,只有一个涉及通道位置或可以更改其文件大小的操作可能正在进行中; 在第一个操作仍在进行时尝试启动第二个此类操作将阻塞,直到第一个操作完成.其他操作,特别是那些采取明确立场的操作,可以同时进行; 他们实际上是否这样做取决于基本的实施,因此没有具体说明.

所以我建议先尝试一下,看看你要部署代码的OS(可能是文件系统类型)是否支持并行执行一个FileChannel.write调用

编辑:正如所指出的,上面并不意味着线程可以同时写入文件,它实际上是相反的,因为write调用根据WritableByteChannel的合同行为,它明确指定一次只有一个线程可以写入给定的文件:

如果一个线程在通道上启动写操作,则尝试启动另一个写操作的任何其他线程将阻塞,直到第一个操作完成



2> Gerald Mücke..:

正如文档所述并且Adonis已经提到过这一点,写入一次只能由一个线程执行.你不会通过concurreny获得性能提升,而且,如果这是一个实际问题你应该只担心性能,因为同时写入磁盘可能会降低你的性能(SSD可能比HDD更少).

在大多数情况下,底层媒体(SSD,HDD,网络)是单线程的 - 实际上,硬件级别上没有线程,线程只不过是抽象.

在您的情况下,媒体是SSD.虽然SSD内部可以同时向多个模块写入数据(它们可能达到平均值,写入速度可能快,甚至优于读取),但内部映射数据结构是共享资源,因此可以争用,尤其是在频繁更新(如并发)时写道.尽管如此,这种数据结构的更新速度非常快,因此除非出现问题,否则无需担心.

但除此之外,这些只是SSD的内部.在外部,您通过串行 ATA接口进行通信,因此一次一个字节(实际上是帧信息结构中的数据包,FIS).最重要的是OS/Filesystem再次具有可能的竞争数据结构和/或应用他们自己的优化方法,例如后写缓存.

此外,正如您所知道的媒体是什么,您可以特别优化它,当一个线程写入大量数据时,SSD非常快.

因此,您可以创建一个大的内存缓冲区(可能考虑一个内存映射文件),并同时写入此缓冲区,而不是使用多个线程进行写入.只要你确保每个线程访问它自己的缓冲区地址空间,内存本身就没有争用.完成所有线程后,将此缓冲区写入SSD(如果使用内存映射文件则不需要).

另请参阅关于SSD开发的这个很好的总结: 摘要 - 每个程序员应该了解固态驱动器

进行预分配(或者更确切地说,file_.setLength()实际映射到的ftruncate)的重点是文件的大小调整可能会使用额外的周期,你可能不想避免这种情况.但同样,这可能取决于OS/Filesystem.


推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
author-avatar
手机用户2702934510
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有