我正在尝试在Java中实现线程并发。它包括尝试最后一次写入文件。有两个线程:A
- 创建一个文件并检查文件中是否有正确的行和B
- 正在搜索文件并尝试用“好”重写文件线。 “获胜者”主题必须在文件中包含字符串。要做它的线程检查文件是否有他们的行,文件只有一行。线程只有文件路径。
public class A implements Runnable {
private File file;
private Thread t;
public A(String patch,String fileName)
{
t = new Thread(this);
CreateFile(patch, fileName);
//t.setDaemon(true);
t.start();
}
@Override
public void run() {
BufferedReader reader;
while (!Thread.currentThread().isInterrupted()) {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
if (reader.readLine().charAt(0) == 'B') {
System.out.println("A try took file: " + file.getName());
write();
} else {
System.out.println("A took file: " + file.getName());
}
} catch (FileNotFoundException e)
{
System.out.println("File read A" + e.toString());
}
catch (IOException e)
{
System.out.println("File read A"+e.toString());
}
}
}
private void write() {
try {
PrintWriter printWriter = new PrintWriter(file);
printWriter.println("A took file: " + file.getName());
System.out.println("A took file: " + file.getName());
printWriter.close();
} catch (Exception e) {
System.out.println("File write A");
}
}
public File CreateFile(String patch,String fileName) {
File file = new File(patch,fileName+".txt");
try {
PrintWriter printWriter = new PrintWriter(file);
printWriter.println("A took file: " + file.getName());
System.out.println("A took file: " + file.getName());
printWriter.close();
} catch (Exception e) {
System.out.println("File create A");
}
return file;
}
}
public class B implements Runnable {
private File file;
private Thread t;
public B(String patch,String fileName)
{
t = new Thread(this);
//t.setDaemon(true);
FindFile(patch, fileName);
t.start();
}
@Override
public void run() {
BufferedReader reader;
while (!Thread.currentThread().isInterrupted()) {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
if (reader.readLine().charAt(0) == 'A') {
System.out.println("B try took file: " + file.getName());
write();
} else {
System.out.println("B took file: " + file.getName());
}
} catch (FileNotFoundException e)
{
System.out.println("File read B" + e.toString());
}
catch (IOException e)
{
System.out.println("File read B"+e.toString());
}
}
}
private void write() {
try {
PrintWriter printWriter = new PrintWriter(file);
printWriter.println("B took file: " + file.getName());
System.out.println("B took file: " + file.getName());
printWriter.close();
} catch (Exception e) {
System.out.println("File write B");
}
}
public File FindFile(String patch,String fileName) {
File file= null;
File folder = new File(patch);
File[] listOfFiles = folder.listFiles();
BufferedReader reader;
for (int i = 0; i < listOfFiles.length; i++) {
file = listOfFiles[i];
if (file.getName().equals(fileName + ".txt")) {
break;
}
}
return file;
}
}
我希望以某种方式同步访问线程中的文件。在我的代码中,当我使用java.lang.NullPointerException
时,我有readLine()
,所以我认为这是因为线程没有对文件的同步访问(在每个完成的操作文件必须有一行之后)。我不能使用synchronized方法或块,因为线程没有文件的联合变量。有没有办法在文件中进行同步写作和阅读?
答案 0 :(得分:0)
您可以使用 ReentrantReadWriteLock 进行同步。解析相同的锁以同步A和B.这里我修改了B.你也可以为A做同样的事。
public static class B implements Runnable {
private File file;
private Thread t;
private ReentrantReadWriteLock lock;
public B(String patch,String fileName, ReentrantReadWriteLock lock)
{
t = new Thread(this);
this.lock = lock;
//t.setDaemon(true);
FindFile(patch, fileName);
t.start();
}
@Override
public void run() {
BufferedReader reader;
while (!Thread.currentThread().isInterrupted()) {
try {
lock.readLock().lock();
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
if (reader.readLine().charAt(0) == 'A') {
lock.readLock().unlock();
lock.writeLock().lock();
System.out.println("B try took file: " + file.getName());
write();
lock.writeLock().unlock();
} else {
System.out.println("B took file: " + file.getName());
}
} catch (FileNotFoundException e)
{
System.out.println("File read B" + e.toString());
}
catch (IOException e)
{
System.out.println("File read B"+e.toString());
}
}
}
private void write() {
try {
PrintWriter printWriter = new PrintWriter(file);
printWriter.println("B took file: " + file.getName());
System.out.println("B took file: " + file.getName());
printWriter.close();
} catch (Exception e) {
System.out.println("File write B");
}
}
public File FindFile(String patch,String fileName) {
File file= null;
File folder = new File(patch);
File[] listOfFiles = folder.listFiles();
BufferedReader reader;
for (int i = 0; i < listOfFiles.length; i++) {
file = listOfFiles[i];
if (file.getName().equals(fileName + ".txt")) {
break;
}
}
return file;
}
}