使用阻塞 IO 的多线程会损坏 Java 中的文件

2024-01-08

AIM :-使用 Java 中的阻塞 IO 构建多线程应用程序来下载文件。请不要建议我使用非阻塞 IO,我被告知要使用这个。

Issue :-我的代码在下载服务器上托管的文件的客户端计算机上运行良好。但是,问题是我的服务器使用多个线程播种文件。在所有情况下,收到的文件的长度都是准确的,但是文件似乎已损坏。例如,当我下载 PDF 文件时,文件页面已写到最后一页(意味着所有页面都填充了原始内容的部分内容)。当我下载一首歌曲时,它会在整个过程中突然爆发并伴随着这些噪音比特播放到最后。

问题 1:-我应该如何保持完美流畅的下载,以便文件正确播放/打开/读取?我应该在这里解决诸如多线程问题之类的技术问题吗?

我的代码:-

服务器多线程代码:::

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class FileServer extends UnicastRemoteObject implements FileServerInitialise{

private String file="";
public FileServer() throws RemoteException{
    super();
}

public void setFile(String f){
    file=f;
    //System.out.println("Length in setFile = "+f);
}

@Override
public boolean login(FileClientInitialise fci) throws RemoteException {
    try {
        InputStream is = new BufferedInputStream(new FileInputStream(file));
        long len = new File(file).length();
        System.out.println("Length of File = "+len);
        WorkerThread wt1=new WorkerThread(0,len/2,fci,is,file);
        wt1.setName("Worker Thread 1");
        WorkerThread wt2=new WorkerThread(len/2+1,2*len/2,fci,is,file);
        wt2.setName("Worker Thread 2");
        //WorkerThread wt3=new WorkerThread(2*len/4+1,3*len/4,fci,is,file);
        //wt3.setName("Worker Thread 3");
        //WorkerThread wt4=new WorkerThread(3*len/4+1,len,fci,is,file);
        //wt4.setName("Worker Thread 4");
        wt1.start();
        wt2.start();
        //wt3.start();
        //wt4.start();
        wt1.join();
        wt2.join();
        //wt3.join();
        //wt4.join();
        return true;
    }
        catch (InterruptedException iex) {          
        iex.getMessage();
        return false;
        } 

客户端下载代码:::

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

public class FileClient implements FileClientInitialise {
public static int count = 1;
public static File f;
public static FileOutputStream fos;
public static RandomAccessFile raf;
public static long pointer;

public FileClient (String filename) throws RemoteException, IOException {
super();
FileClient.f= new File(filename);
FileClient.fos = new FileOutputStream(f, true);
//FileClient.raf= new RandomAccessFile(f,"rwd");
FileClient.pointer=0;
}

@Override
public boolean sendData(String filename, byte[] data, int len, String threadName) throws RemoteException{
try{

FileClient.fos.write(data,0,len);
FileClient.fos.flush();
//FileClient.raf.seek(FileClient.pointer);
//FileClient.raf.write(data,0, len);
//FileClient.pointer=raf.getFilePointer();
System.out.println("Done writing data...");
//fos.close();
return true;

}catch(Exception e){
e.getMessage();
return false;
}
}
}

问题2 :-另外,我应该使用RandomAccessFile达到同样的目的?会不会更好一些?我检查了一下,它运行速度非常慢(几乎慢了 10 倍)。而且,如果我要使用RandomAccessFile,我应该为每个线程创建一个单独的对象吗?如果在这种情况下建议的话,我应该如何使用它?

如果代码不可能,请给我一个技术描述,代码不必在答案中提及。


正如其他人在评论中已经提到的那样,这是一种糟糕的方法,允许多个线程共享输入流并允许并发写入,从而导致文件损坏。

我在多线程分布式文件服务器项目中执行的一种方法是允许文件服务器的多线程执行,但仅允许顺序线程执行。

我以这种方式进行编码,以确保线程以同步方式(仅一一方式)访问输入流。这也没有损坏客户端的文件。而且,这样的表现效果也太惊人了。

注意,在对此答案采取任何行动之前:-

当时我对代码进行了基准测试,以确保我在这个答案中所说的内容对于访问者/寻求者来说确实是最佳的。我认为这是最佳情况,因为我有 4 个逻辑处理器(核心/CPU),这减少了多个线程的开销(尽管它们一次都工作 1 个)。

人们会认为这是最糟糕的方法,或者是一种丑陋的方法,等等。但我发现这对于文件服务器播种非常有帮助。我的 40 MB(大约)PDF 文件位于Linux Server [Intel(R) Core(TM) 2 Duo CPU E4600 @ 2.40GHz processor, CPU(s): 2]在 4-5 次执行测试中,复制到文件客户端的时间平均为 33-34 秒。然而,当我增加线程数量(8-10 个线程)时,性能下降了大约 36-38 秒。当我使用单线程服务器时也是如此,在 45-50 秒内复制相同的文件。随着线程数量的增加,性能有所提高,在4-6个线程范围内效率较高。

不过,维护如此多的线程显然会产生开销,而且人们会认为单个线程可以获胜,但是,令人惊讶的是,在 4-6 个线程的情况下,结果是最佳的。

因此,我的建议是按照代码所示继续,通过 4-6 个线程执行输入流的顺序访问。这是最优的,相信我,我也可以与其他人争论多线程开销,我发现在 4-6 个线程的情况下这是最优的。

对于您的代码,我建议进行以下更改:-

InputStream is = new BufferedInputStream(new FileInputStream(file));
        long len = new File(file).length();
        System.out.println("Length of File = "+len);
        int numOFThreads=4;
        WorkerThread wt1=new WorkerThread(0,len/numOFThreads,fci,is,file);
        wt1.setName("Worker Thread 1");
        WorkerThread wt2=new WorkerThread(len/numOFThreads+1,2*len/numOFThreads,fci,is,file);
        wt2.setName("Worker Thread 2");
        WorkerThread wt3=new WorkerThread(2*len/numOFThreads+1,3*len/numOFThreads,fci,is,file);
        wt3.setName("Worker Thread 3");
        WorkerThread wt4=new WorkerThread(3*len/numOFThreads+1,4*len/numOFThreads,fci,is,file);
        wt4.setName("Worker Thread 4");
        wt1.start();
        wt1.join();
        wt2.start();
        wt2.join();
        wt3.start();
        wt3.join();
        wt4.start();
        wt4.join();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用阻塞 IO 的多线程会损坏 Java 中的文件 的相关文章

  • 如何打印整个字符串池?

    我想打印包含文字的整个字符串池String使用添加的对象intern 就在垃圾收集之前 JDK有没有隐式的方法来进行这样的操作 我们如何检查字符串池 EDIT The comment suggests that there may be a
  • 将链接对象转换为流或集合

    我想迭代堆栈跟踪 堆栈跟踪由可抛出对象组成 其 getCause 返回下一个可抛出对象 最后一次调用 getCause 返回 null 示例 a gt b gt null 我尝试使用 Stream iterable 这会导致 NullPoi
  • JTree 节点不会被直观地选择

    不知何故 我无法为我的 JTree 节点启用 选择突出显示 我正在我的项目中使用自定义单元格渲染器 这很可能导致此问题 这是完整的渲染器类代码 protected class ProfessionTreeCellRenderer exten
  • 有没有好的方法来解析用户代理字符串?

    我有一个Java接收模块User Agent来自最终用户浏览器的字符串的行为需要略有不同 具体取决于浏览器类型 浏览器版本甚至操作系统 例如 FireFox 7 0 Win7 Safari 3 2 iOS9 我明白了User Agent由于
  • 使用 Spring 时实例化对象,用于测试与生产

    使用 Spring 时 应该使用 Spring 配置 xml 来实例化生产对象 并在测试时直接实例化对象 这样的理解是否正确 Eg MyMain java package org world hello import org springf
  • Google Inbox 类似 RecyclerView 项目打开动画

    目前 我正在尝试实现 Google Inbox 例如RecyclerView行为 我对电子邮件打开动画很好奇 我的问题是 该怎么做 我的意思是 他们使用了哪种方法 他们用过吗ItemAnimator dispatchChangeStarti
  • 方法断点可能会大大减慢调试速度

    每当向方法声明行添加断点 在 Intellij IDEA 或 Android Studio 中 时 都会出现一个弹出窗口 方法断点可能会大大减慢调试速度 为什么会这样戏剧性地减慢调试速度 是我的问题吗 将断点放在函数的第一行有什么不同 Th
  • PropertySources 中各种源的优先级

    Spring引入了新的注释 PropertySources对于所有标记为的类 Configuration since 4 0 需要不同的 PropertySource作为论证 PropertySources PropertySource c
  • 为什么我在 Mac 上看到“java.lang.reflect.InaccessibleObjectException: Unable to make private java.nio.DirectByteBuffer(long,int)accessibl

    我已经在工作中愉快地构建代码好几天了 但突然我的一个项目 不是全部 失败并出现此错误消息 看看下面的答案吧 我是如何修复它的 起初我用谷歌搜索 看到很多有这个问题的人正在使用 Java 16 但我认为 错误 我正在使用 Java 11 因为
  • 参数动态时如何构建 JPQL 查询?

    我想知道是否有一个好的解决方案来构建基于过滤器的 JPQL 查询 我的查询太 富有表现力 我无法使用 Criteria 就像是 query Select from Ent if parameter null query WHERE fiel
  • tomcat 过滤所有 web 应用程序

    问题 我想对所有网络应用程序进行过滤 我创建了一个过滤器来监视对 apache tomcat 服务器的请求 举例来说 它称为 MyFilter 我在 netbeans 中创建了它 它创建了 2 个独立的目录 webpages contain
  • 让JScrollPane控制多个组件

    对于我的应用程序 我正在设计一个脚本编辑器 目前我有一个JPanel其中包含另一个JPanel保存行号 位于左侧 以及JTextArea用于允许用户输入代码 位于右侧 目前 我已经实施了JScrollPane on the JTextAre
  • 如何使用 Mockito 和 Junit 模拟 ZonedDateTime

    我需要模拟一个ZonedDateTime ofInstant 方法 我知道SO中有很多建议 但对于我的具体问题 到目前为止我还没有找到任何简单的解决办法 这是我的代码 public ZonedDateTime myMethodToTest
  • 不兼容的类型:在 java netbeans 中对象无法转换为 String

    我试图在我的项目中使用对象数组 但出现错误 incompatible types Object cannot be converted to String 在这一行 ST1 new String emt1 emt2 emt3 emt4 现在
  • 如何在keycloak中动态编辑standalone.xml文件

    我正在尝试通过 docker 编辑standalone xml 并尝试添加 但 keycloak 正在使用它standalone xml 但我可以看到standalone xml 文件中的更改 我需要在standalone xml 文件中添
  • ExceptionHandler 不适用于 Throwable

    我们的应用程序是基于 Spring MVC 的 REST 应用程序 我正在尝试使用 ExceptionHandler 注释来处理所有错误和异常 I have ExceptionHandler Throwable class public R
  • 如何在android sdk上使用PowerMock

    我想为我的 android 项目编写一些单元测试和仪器测试 然而 我遇到了一个困扰我一段时间的问题 我需要模拟静态方法并伪造返回值来测试项目 经过一些论坛的调查 唯一的方法是使用PowerMock来模拟静态方法 这是我的 gradle 的一
  • 如何移动图像(动画)?

    我正在尝试在 x 轴上移动船 还没有键盘 我如何将运动 动画与boat png而不是任何其他图像 public class Mama extends Applet implements Runnable int width height i
  • Spring Boot MSSQL Kerberos 身份验证

    目前在我的春季靴子中application properties文件中 我指定以下行来连接到 MSSql 服务器 spring datasource url jdbc sqlserver localhost databaseName spr
  • 尝试使用带有有效购买令牌的 Java Google Play Developer API v3 检索应用内购买信息时出现错误请求(无效值)

    当使用 Java Google Play Developer API 版本 3 并请求有效购买令牌的购买信息时 我收到以下异常 API 调用返回 400 Bad Request 响应以及以下消息 code 400 errors domain

随机推荐

  • 使用 Sphinx 生成 PHP 代码文档? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Sphinx 是一个 Python 库 用于从一组 ReST 格式的文本文件生成漂亮的文档 不是用于全文检索的工具 我也完全了解 do
  • 在 shell 脚本中将一个文件中的 key:value 替换到另一个文件中?

    我有一个包含键值条目的 数据库文件 还有另一个文件 其中键出现在其他内容中 现在我想用我的键值文件的值替换该关键字 例子 有一个文件 keys txt 其中包含 关键字空间 url name1 https maps google com s
  • set 与 unordered_set 的最快迭代

    在我的申请中 我有以下要求 数据结构将仅使用一些值 不是键 值对 填充一次 这些值可能会重复 但我希望数据结构只存储它们一次 我将迭代上面创建的数据结构的所有元素 100 次 元素在迭代中出现的顺序并不重要 约束 1 表明我必须使用 set
  • 将电源计划更改为高性能

    如何将本地计算机上的电源计划更改为高性能 并更改选项 之后关闭显示 我想设置为从不 我找到了远程计算机的所有示例 您可以通过调用来做到这一点activate方法中的Win32 PowerPlan class powerPlan Get Wm
  • 如何获取 Django 视图集中的 API 参数?

    我正在构建一个公开 REST API 的 Django 应用程序 用户可以通过该 API 查询我的应用程序的模型 我正在按照说明进行操作here http www django rest framework org tutorial qui
  • 在 CDI 实现项目中包含空 beans.xml 的目的是什么?

    我在用weld CDI 的 RI 作为我的 JSF EJB JPA Web 应用程序中的依赖项注入组件 我看到在我的项目中我们有空的 beans xmlMETA INF beans xml in ejb jar and WEB INF be
  • 使用 JAX-RS 和 Jackson 将 JPA 实体转换为 REST 表示的最佳方法

    我正在寻找一种将一些 JPA 实体导出到 REST API 的方法 但不是每次我想根据入口点共享一些特定字段时都发送整个实体 这是一个小例子 假设我们有一个Author具有很少字段的类 Entity public class Author
  • YouTube iframe api 未触发 onYouTubeIframeAPIReady

    我已经与 youtube iframe api 斗争了一段时间了 不知怎的方法onYouTubeIframeAPIReady并不总是被触发 从症状来看 似乎是负载问题 检查器中没有显示任何错误 这是我的代码 HTML div div
  • Emscripten 找不到 cmake 的路径

    我已经将说明仔细阅读了好几遍 https kripken github io emscripten site docs getting started downloads html 查了无数论坛 还是无法解决这个问题 我正在运行 Windo
  • 是否可以用现有图中的常量替换占位符?

    我有一张经过训练的模型的冻结图 它有一个tf placeholder我总是向其提供相同的价值 我想知道是否可以将其替换为tf constant反而 如果是这样的话 任何例子将不胜感激 编辑 这是代码的样子 以帮助可视化问题 我正在使用 由其
  • WCF:从另一方收到不安全或安全错误的错误

    我创建了一项具有 aspnet 角色和安全性的 WCF 服务 当我在一个网站上使用它并尝试检查是否使用正确的用户名和密码时 它工作得很好 但是如果用户名和密码不正确 它会给我一个错误 从对方收到不安全或不正确安全的故障 派对 有关错误代码和
  • 从终端构建、部署和运行 iphone 模拟器

    我是 mac 和 xcode 的新手 请告诉我 iphone xcodeproject 在 xcode IDE 之外执行以下任务的过程 使用 xcodebuild 命令构建完成 在模拟器中部署 在模拟器中运行 如何使用 ant Apples
  • 默认参数的词法声明问题[重复]

    这个问题在这里已经有答案了 我在定义一些时遇到一些问题功能声明后class 我用的是默认的params之前在声明函数时 但我不知道是否也可以使用函数或类作为默认参数 我的代码是这样的 const Matrix class some code
  • Jquery .on 与双击事件

    为什么这会起作用 document on dblclick areaA tr has td function e code here 这并不 areaA tr has td on dblclick function e Code here
  • 为什么匿名类中只能访问最终变量?

    a只能在这里最终决定 为什么 我怎样才能重新分配a in onClick 方法而不将其保留为私有成员 private void f Button b final int a b addClickHandler new ClickHandle
  • 为什么缺少 object.__getattr__ ?

    为什么object似乎没有 getattr 方法 它定义了两者 setattr and delattr 这三个都不需要吗 gt gt gt object setattr
  • CNContact 标识符中的“:ABPerson”字符串是什么?

    我的 iOS 应用程序会时不时地检查联系人并将新联系人导入到自己的数据库中 我检查了该联系人 它已经存在identifier字段 通常由 UUID 填充 CNContactStore store CNContactStore new sto
  • 关闭 Tkinter 后运行 wxPython

    我们有两个应用程序 一个使用 Tkinter 界面开发 另一个使用 wxPython 构建 两者都相当复杂 运行完 Tkinter 应用程序后 我希望在选择 Tkinter 应用程序中的按钮后运行 wxPython 应用程序 是否可以切换事
  • 在 PHP 中将段落分解为句子

    我一直在使用 explode mystring 将段落拆分成句子 然而 这不包括用不同标点符号结束的句子 例如 有没有办法使用数组而不是单个字符作为分隔符 或者还有另一种使用各种标点符号进行拆分的巧妙方法吗 I tried explode
  • 使用阻塞 IO 的多线程会损坏 Java 中的文件

    AIM 使用 Java 中的阻塞 IO 构建多线程应用程序来下载文件 请不要建议我使用非阻塞 IO 我被告知要使用这个 Issue 我的代码在下载服务器上托管的文件的客户端计算机上运行良好 但是 问题是我的服务器使用多个线程播种文件 在所有