英文:
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.
-
It is required to set a 1 millisecond pause for writing of each digit.
-
Use the RandomAccessFile for writing data to the file.
-
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("");
for(int i = 0; i < 20; i++){
result.append(integer);
}
result.append("\n");
return result.toString();
}
// writes string into the file
public static void writeString(String st) {
try(RandomAccessFile file = new RandomAccessFile("part5.txt", "rw")){
st+="\n";
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 < 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("");
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();
}
}
}
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论