如何从多个线程输出到.txt文件?

发布于 2025-02-11 18:07:26 字数 1871 浏览 1 评论 0原文

这是我当前的线程,我用它来压力测试CPU,我需要每小时输出每小时的“ hcount”到.txt文件,目前,它将打印出来,但只有从一个线程中,当另一个小时通过时,它会删除什么写在.txt文件上并重写新的“ hcount” 我正在运行3个线程。

import java.util.Random;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class MyThread extends Thread{
    public void run() {
        String B;//Will hold the value of Cpointer
        String A;//will hold the string value of Hcount
        Path fileName =
                Path.of("D:/EEoutput/Out.txt");
        Random rand = new Random();
        long Hcount = 0;//counts the number of iterations in an hour
        long t = System.currentTimeMillis();
        long end = t + 3800000*5;//a minute
        double a1 = 0; //random holder 1
        double a2 = 0;//random holder 2
        double answer = 0; // answer placeholder
        Long hour = System.currentTimeMillis()+3600000;//will be used to say when are we outputing the number of iterations to the file
        int Cpointer = 1;//will tell how many hours has passed
        while (System.currentTimeMillis() < end) {
            a1 = rand.nextDouble();
            a2 = rand.nextDouble();
            answer = a1 * 23 / (a2 + a1) + a2;
            Hcount++;
            if (System.currentTimeMillis() >= hour)// checks if the program needs to
            {
                 B = String.valueOf(Cpointer);
                 A=String.valueOf(Hcount);
                try {
                    Files.writeString(fileName, A);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                hour = System.currentTimeMillis()+3600000;//sets stop to next hour
                Cpointer++;//declares that another hour has passed, will be used to tell how many iterations are there in a certain hour
                Hcount = 0;
            }
        }

    }
}
'''

This is my current thread, I use it to stress test the CPU, I need to output the "Hcount" every hour to a .txt file, currently, it will print it but only from one thread ,when another hour passes it deletes what is written on the .txt file and rewrite the new "Hcount"
I'm Running 3 threads.

import java.util.Random;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class MyThread extends Thread{
    public void run() {
        String B;//Will hold the value of Cpointer
        String A;//will hold the string value of Hcount
        Path fileName =
                Path.of("D:/EEoutput/Out.txt");
        Random rand = new Random();
        long Hcount = 0;//counts the number of iterations in an hour
        long t = System.currentTimeMillis();
        long end = t + 3800000*5;//a minute
        double a1 = 0; //random holder 1
        double a2 = 0;//random holder 2
        double answer = 0; // answer placeholder
        Long hour = System.currentTimeMillis()+3600000;//will be used to say when are we outputing the number of iterations to the file
        int Cpointer = 1;//will tell how many hours has passed
        while (System.currentTimeMillis() < end) {
            a1 = rand.nextDouble();
            a2 = rand.nextDouble();
            answer = a1 * 23 / (a2 + a1) + a2;
            Hcount++;
            if (System.currentTimeMillis() >= hour)// checks if the program needs to
            {
                 B = String.valueOf(Cpointer);
                 A=String.valueOf(Hcount);
                try {
                    Files.writeString(fileName, A);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                hour = System.currentTimeMillis()+3600000;//sets stop to next hour
                Cpointer++;//declares that another hour has passed, will be used to tell how many iterations are there in a certain hour
                Hcount = 0;
            }
        }

    }
}
'''

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦纸 2025-02-18 18:07:26

从多个线程中写入文件是一个坏主意。我建议您创建一个队列(即使只是在内存队列中),并让所有线程写入他们要将您的文件写入此队列中的信息。换句话说,您的队列将有多个生产商。而您的队列中的一个消费者将从队列中读取并将其写入您的文件中。这样,您只会将一个线程写入文件中

Writing into file from multiple threads is a bad idea. I suggest you create a queue (even if just in memory queue) and have all your threads writing the info that they want to write into your file into this queue. In other words your queue will have multiple producers. And than have a single consumer on your queue that will read from the queue and write it into your file. This way you will have only one thread writing into file

迟到的我 2025-02-18 18:07:26

您在这里有两个单独的问题。

  • files.writestring默认替换内容。您需要files.writestring(文件名,a,standardOpenoption.append)
  • 从同时线程中写入同一文件无法使用(考虑一下。操作系统不能保证您的写入将是原子,这应该很明显)。因此,即使您修复了它,它也会工作,但每一次都会失败:种族条件。

围绕最后一部分的通常策略是使用某种锁。如果单个JVM是唯一做这些文件写入的人,则可以使用Java提供的任何内容:同步。或ReadWritelock来自JuconCurrent软件包。

但是,这确实意味着您的CPU压力螺纹将进行锁定。相反,您可能想启动一个单独的线程,并具有单个cromentblockingquequeue。您的CPU压力测试仪将日志消息发送到队列,您的日志作者线程将进行5台循环:无休止地从队列中获取项目(这是块直到有东西),将其写入文件,齐平流和循环。

鉴于现在只有一个线程写作,这解决了很多问题。

如果是多个JVM,那很棘手 - 然后用.lock文件锁定。您可以使用files.createfile()来创建logfile.lock;如果文件已经存在,这将失败。然后等待一些时间(您不能要求操作系统告诉您何时删除文件,因此您必须等待半秒钟左右,然后再一次检查,直到文件消失),直到该文件成功,然后写写。 ,然后删除锁定文件。

.lock文件的一个主要缺点是:如果您的进程硬碰撞,则锁定文件会粘住。你不想要的。 的一种解决方案是,是为其编写自己的pid(过程ID),因此,任何进行检查的人至少都可以看到它所属的过程已经死了。除了这很棘手;现代的OS不仅让您确定地检查存在,而且据我所知,这都是非常依赖OS的依赖性(没有可自动化这些东西的Java库)。这一切都变得非常复杂,因此,让我们保持简单:

如果您想同时从同一系统上的不同JVM /进程同时写入同一文件,那么您 can can < / em> < / em>做“安全”,但是相当复杂。

You have two separate issues here.

  • Files.writeString replaces content by default. You want Files.writeString(fileName, A, StandardOpenOption.APPEND).
  • Writing to the same file from simultaneous threads isn't going to work (think about it. The OS cannot promise that your write will be atomic, that should be obvious). So even if you fix it, it'll seem to work but every so often fail on you: A race condition.

The usual strategy to work around that last part is to use locks of some kind. If a single JVM is the only one doing those file writes, you can use whatever you like that java offers: synchronized, for example. Or an ReadWriteLock from the j.u.concurrent package.

But, this does mean your CPU stresser thread will be doing the waiting for the lock. You may instead want to start a separate thread, and have a single ConcurrentBlockingQueue. Your CPU stress testers send log messages to the queue, and your log writer thread will just be doing a 5-liner loop: Endlessly, fetch an item from the queue (this blocks until there is something), write it to the file, flush the stream, and loop.

This solves a bunch of problems, given that now only one thread writes.

If it's multiple JVMs, that's trickier - then lock with a .lock file. You can use Files.createFile() to create logfile.lock; this will fail if the file is already there. Then wait some time (you can't ask the OS to tell you when the file is deleted, so you have to wait half a second or so and check again, forever, until the file is gone), until it succeeds, then write, then delete the lock file.

A major downside to .lock files is: If your process hard-crashes, the lock file sticks around. Which you don't want. One solution to that is to write your own PID (Process ID) to it, and thus anybody doing a check can at least see that the process it belongs to is dead. Except this is tricky; modern OSes don't just let you check for existence, neccessarily, and it's all very OS-dependent (no java libraries that automate this stuff, as far as I know). This all gets quite complicated, so, let's keep it simple:

If you want to write to the same file simultaneously from different JVMs / processes on the same system, you can do that 'safely', but it is rather complicated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文