面试题答案
一键面试- 原理:
synchronized
关键字可以用于修饰方法或代码块。当一个线程进入被synchronized
修饰的方法或代码块时,它会自动获取对象的锁。其他线程在该锁被释放前无法进入相同对象的同步代码块或方法,从而保证同一时间只有一个线程执行同步的代码,实现线程安全。- 对于
FileOutputStream
,可以通过对FileOutputStream
对象或者包含FileOutputStream
操作的类实例对象加锁来确保I/O操作的线程安全。
- 示例代码:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class ThreadSafeFileWriter {
private final OutputStream outputStream;
public ThreadSafeFileWriter(String filePath) throws IOException {
this.outputStream = new FileOutputStream(filePath);
}
public void writeToFile(String content) {
synchronized (this) {
try {
outputStream.write(content.getBytes());
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void close() {
synchronized (this) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在上述代码中,ThreadSafeFileWriter
类封装了FileOutputStream
操作。writeToFile
和close
方法通过synchronized (this)
同步代码块,确保同一时间只有一个线程可以执行这些I/O操作,从而保证线程安全。使用示例如下:
public class Main {
public static void main(String[] args) {
try {
ThreadSafeFileWriter writer = new ThreadSafeFileWriter("test.txt");
Thread thread1 = new Thread(() -> writer.writeToFile("Hello from thread 1"));
Thread thread2 = new Thread(() -> writer.writeToFile("Hello from thread 2"));
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在这个Main
类中,创建了两个线程同时调用writeToFile
方法,由于writeToFile
方法中的I/O操作是同步的,所以不会出现数据混乱的问题。