将数据同时写入文本文件的多个线程中(同时写入文件的不同行)。

huangapple go评论76阅读模式
英文:

Write data into text file with multiple threads (simultaneously, in different lines of file)

问题

请注意,您的代码中有一些 HTML 转义字符,需要删除。以下是修复了您的代码的并发部分,以使其按预期工作:

import java.io.IOException;
import java.io.RandomAccessFile;

public class Part5 {
    // creates string before writing to the file
    public static String createString(int integer){
        StringBuilder result = new StringBuilder("");

        for(int i = 0; i < 20; i++){
            result.append(integer);
        }

        result.append("\n");
        return result.toString();
    }
    
    // writes string into the file
    public static synchronized void writeString(String st, RandomAccessFile file) {
        try {
            st += "\n";
            file.write(st.getBytes());
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    // starts writing threads
    public static void startThread(int number, RandomAccessFile file){
        Thread thread = new Thread(){
            @Override
            public void run() {
                synchronized (file) {
                    writeString(createString(number), file);
                }
            }
        };

        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(final String[] args) {
        try (RandomAccessFile file = new RandomAccessFile("part5.txt", "rw")) {
            for (int i = 0; i < 10; i++) {
                startThread(i, file);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这个修复的版本在主函数中打开了一个 RandomAccessFile 对象,并将其传递给 startThread 函数。每个线程在写入文件时都要使用 synchronized 块来确保线程安全性。这样,您的代码应该能够正确地生成所需的输出。

英文:

Create k threads that simultaneously write characters into the same file:

  • the first thread writes a digit 0 exactly 20 times on the first line of the file;
  • the second thread writes a digit 1 exactly 20 times on the second line of the file;
    >...
  • the tenth thread writes a digit 9 exactly 20 times on the tenth line of the file;

Requirements to the implementation.

  1. It is required to set a 1 millisecond pause for writing of each digit.

  2. Use the RandomAccessFile for writing data to the file.

  3. You can use not more than one object of the RandomAccessFile class!

I wrote something like this:

import java.io.IOException;
import java.io.RandomAccessFile;
public class Part5 {
// creates string before writing to the file
public static String createString(int integer){
StringBuilder result = new StringBuilder(&quot;&quot;);
for(int i = 0; i &lt; 20; i++){
result.append(integer);
}
result.append(&quot;\n&quot;);
return result.toString();
}
// writes string into the file
public static void writeString(String st) {
try(RandomAccessFile file = new RandomAccessFile(&quot;part5.txt&quot;, &quot;rw&quot;)){
st+=&quot;\n&quot;;
file.write(st.getBytes());
}catch(IOException ex){
ex.getMessage();
}
}
// starts writing threads
public static void startThread(int number){
Thread thread = new Thread(){
@Override
public void run() {
synchronized (this){
writeString(createString(number));
}
}
};
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(final String[] args) {
for(int i = 0; i &lt; 9; i++){
startThread(i);
}
}
}

My implementation only rewrites first line of the file, but should write something like this:

00000000000000000000
11111111111111111111 
22222222222222222222 
33333333333333333333 
44444444444444444444 
55555555555555555555 
66666666666666666666 
77777777777777777777 
88888888888888888888 
99999999999999999999

How can I fix my "concurrency part" of code to make it work correctly?
Thank you in advance!

答案1

得分: 0

Here is the translated code:

当你写入文件时需要将指针移动到正确的位置你需要调用RandomAccessFile中的seek方法然后移动指针指定的字节数例如第一个线程将会seek到0第二个线程将会seek到21依此类推

目前你的程序的方式每个线程都会覆盖其他线程的内容

并行化也可能存在问题

我不想提供现成的解决方案但我变得好奇所以这是你可以学习的内容

```java
import java.io.IOException;
import java.io.RandomAccessFile;

public class Blah {
    // 在写入文件之前创建字符串
    public static String createString(int integer){
        StringBuilder result = new StringBuilder("");

        for(int i = 0; i < 20; i++){
            result.append(integer);
        }

        result.append("\n");
        return result.toString();
    }

    public static void main(final String[] args) throws IOException {
        RandomAccessFile file = new RandomAccessFile("part5.txt", "rw");
        Blah blah = new Blah();
        for(int i = 0; i <= 9; i++){
            Thread thread = new Thread(blah.new NumberWriter(i, file));
            thread.start();
        }

        file.close();
    }

    private class NumberWriter implements Runnable {
        int number;
        RandomAccessFile file;

        public NumberWriter(int number, RandomAccessFile file) {
            this.number = number;
            this.file = file;
        }


        public void run() {
            try {
                int seek = this.number * 20 + number;
                System.out.println("number is  : " + number + " : seeking to : " + seek);

                file.seek(seek);
                file.write((createString(this.number)).getBytes());
            } catch (IOException ioex) {
                ioex.printStackTrace();
            }
        }
    }
}
英文:

When you write to file, you need to move the pointer to the correct position. You need to call "seek" method in RandomAccessFile and then move the pointer by number of bytes. For example first thread will seek to 0, second will seek to 21 and so on.

The way your program is right now, every thread will overwrite every other thread.

There may also be a problem with parallelization.

I didn't want to give a ready made solution, but I got curious. So here's something you could learn from

import java.io.IOException;
import java.io.RandomAccessFile;
public class Blah {
// creates string before writing to the file
public static String createString(int integer){
StringBuilder result = new StringBuilder(&quot;&quot;);
for(int i = 0; i &lt; 20; i++){
result.append(integer);
}
result.append(&quot;\n&quot;);
return result.toString();
}
public static void main(final String[] args) throws IOException {
RandomAccessFile file = new RandomAccessFile(&quot;part5.txt&quot;, &quot;rw&quot;);
Blah blah = new Blah();
for(int i = 0; i &lt;= 9; i++){
Thread thread = new Thread(blah.new NumberWriter(i, file));
thread.start();
}
file.close();
}
private class NumberWriter implements Runnable {
int number;
RandomAccessFile file;
public NumberWriter(int number, RandomAccessFile file) {
this.number = number;
this.file = file;
}
public void run() {
try {
int seek = this.number * 20 + number;
System.out.println(&quot;number is  : &quot; + number + &quot; : seeking to : &quot; + seek);
file.seek(seek);
file.write((createString(this.number)).getBytes());
} catch (IOException ioex) {
ioex.printStackTrace();
}
}
}
}
</details>

huangapple
  • 本文由 发表于 2020年8月6日 00:11:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63269254.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定