如何从多个线程输出到.txt文件?
这是我当前的线程,我用它来压力测试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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从多个线程中写入文件是一个坏主意。我建议您创建一个队列(即使只是在内存队列中),并让所有线程写入他们要将您的文件写入此队列中的信息。换句话说,您的队列将有多个生产商。而您的队列中的一个消费者将从队列中读取并将其写入您的文件中。这样,您只会将一个线程写入文件中
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
您在这里有两个单独的问题。
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 wantFiles.writeString(fileName, A, StandardOpenOption.APPEND)
.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 anReadWriteLock
from thej.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 useFiles.createFile()
to createlogfile.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.