男人和女人做羞羞的免费网站,公司网站制作公司排名,农业网站怎么做,爱站网做网站吗Springboot Java多线程操作本地文件#xff0c;加读写锁#xff0c;阻塞的线程等待运行中的线程执行完再查询并写入1、读写锁2、文件锁3、Synchronized和Lock的区别1、读写锁
在 Spring Boot 中进行多线程操作本地文件并加读写锁可以使用 Java 的 java.nio.file 包中提供的文…
Springboot Java多线程操作本地文件加读写锁阻塞的线程等待运行中的线程执行完再查询并写入1、读写锁2、文件锁3、Synchronized和Lock的区别1、读写锁
在 Spring Boot 中进行多线程操作本地文件并加读写锁可以使用 Java 的 java.nio.file 包中提供的文件操作方法以及 Java 的 java.util.concurrent 包中提供的读写锁来实现。下面是一个示例代码
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class FileReadWriteExample {private static ReentrantReadWriteLock lock new ReentrantReadWriteLock();public static void main(String[] args) {Path path Paths.get(example.txt);Thread writer new Thread(() - {try {lock.writeLock().lock();// 写文件操作Files.writeString(path, Hello World!);} catch (Exception e) {e.printStackTrace();} finally {lock.writeLock().unlock();}});Thread reader new Thread(() - {try {lock.readLock().lock();// 读文件操作String content Files.readString(path);System.out.println(content);} catch (Exception e) {e.printStackTrace();} finally {lock.readLock().unlock();}});writer.start();try {writer.join();} catch (InterruptedException e) {e.printStackTrace();}reader.start();}
}
在这个示例中我们使用 ReentrantReadWriteLock 来实现读写锁确保只有一个线程在执行写操作而多个线程可以同时执行读操作。在这个示例中我们首先创建一个 Path 对象来表示要读写的文件然后创建一个写线程和一个读线程。写线程首先获取写锁然后执行写操作最后释放写锁。读线程获取读锁执行读操作最后释放读锁。
为了确保读线程在写线程执行完毕后再执行我们使用 Thread.join() 方法来等待写线程执行完毕。这样当写线程执行完毕并释放写锁时读线程才能获取读锁并执行读操作。如果读线程在写线程还未执行完毕时尝试获取读锁它会被阻塞直到写线程释放写锁。
2、文件锁
在 Spring Boot 中使用 Java 多线程操作本地文件并加文件锁阻塞的线程等待运行中的线程执行完再查询并写入可以采用以下步骤
使用Java的java.nio.channels.FileChannel类获取文件通道。
创建一个文件锁使用文件通道的lock()方法创建一个文件锁以确保多线程读写文件时的互斥。
创建一个写线程使用Java的java.lang.Thread类创建一个写线程并在该线程中获取文件锁然后执行写操作。
创建一个读线程使用Java的java.lang.Thread类创建一个读线程并在该线程中获取文件锁然后执行读操作。
在主线程中等待写线程执行完毕使用Java的java.lang.Thread类的join()方法在主线程中等待写线程执行完毕。
在主线程中等待读线程执行完毕使用Java的java.lang.Thread类的join()方法在主线程中等待读线程执行完毕。
下面是一个示例代码
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;public class FileReadWriteExample {private static final String FILE_NAME example.txt;public static void main(String[] args) {Thread writerThread new Thread(() - {try (RandomAccessFile file new RandomAccessFile(FILE_NAME, rw);FileChannel channel file.getChannel();FileLock lock channel.lock()) {// 执行写操作channel.write(Hello World!.getBytes());} catch (IOException e) {e.printStackTrace();}});Thread readerThread new Thread(() - {try (RandomAccessFile file new RandomAccessFile(FILE_NAME, r);FileChannel channel file.getChannel();FileLock lock channel.lock(0L, Long.MAX_VALUE, true)) {// 执行读操作String content new String(channel.map(FileChannel.MapMode.READ_ONLY, 0L, channel.size()).array());System.out.println(Content: content);} catch (IOException e) {e.printStackTrace();}});// 启动写线程writerThread.start();try {// 等待写线程执行完毕writerThread.join();} catch (InterruptedException e) {e.printStackTrace();}// 启动读线程readerThread.start();try {// 等待读线程执行完毕readerThread.join();} catch (InterruptedException e) {e.printStackTrace();}}
}在这个示例中我们使用了 FileChannel 和 FileLock 来创建文件锁并在写线程和读线程中分别获取文件锁。 在写线程中我们使用文件通道的 write() 方法来写入数据在读线程中我们使用文件通道的 map() 方法来读取数据。 同时我们还需要在读线程中使用 lock() 方法获取共享锁这样可以确保读线程在写线程执行完毕后再执行避免在主线程中
我们首先启动写线程然后使用 join() 方法等待写线程执行完毕。接着我们启动读线程 并使用 join() 方法等待读线程执行完毕。这样可以确保读线程在写线程执行完毕后才会执行从而确保读取到的数据是完整的。
需要注意的是在使用文件锁时需要根据具体的需求来选择锁类型。在上面的示例中我们在写线程中使用了独占锁lock() 方法在读线程中使用了共享锁lock(0L, Long.MAX_VALUE, true) 方法 这样可以避免写线程和读线程之间的互相干扰。
另外需要注意文件锁的作用范围。在上面的示例中我们只是对整个文件加了锁如果需要对文件中的某一部分加锁 可以使用 lock(long position, long size, boolean shared) 方法来指定锁的位置和大小。 其中position 参数表示锁的起始位置size 参数表示锁的大小shared 参数表示是否为共享锁。 需要注意的是在使用这个方法时需要确保文件通道的当前位置在锁的起始位置上 否则会抛出 NonWritableChannelException 或 NonReadableChannelException 异常。 可以使用 position() 方法来获取或设置文件通道的当前位置。
总之在使用 Java 多线程操作本地文件时加文件锁是一种保证线程安全的有效方式 可以避免多个线程同时读写同一个文件而导致的数据不一致问题。但是需要注意锁的类型和作用范围以及加锁的时机和释放锁的时机以避免出现死锁等问题。
3、Synchronized和Lock的区别
synchronized 和 Lock 都是 Java 中用于实现线程同步的机制它们的主要作用是确保多个线程对共享资源的访问顺序和互斥性从而避免数据竞争和并发访问导致的不一致问题。
以下是 synchronized 和 Lock 的主要区别
1、范围synchronized 是 Java 内置的关键字可以用于同步方法和同步代码块而 Lock 是一个接口需要通过实现类来使用。
2、锁的类型synchronized 是隐式锁即 JVM 自动为我们加锁和释放锁而 Lock 是显式锁需要手动加锁和释放锁。
3、性能在 Java 5 之前synchronized 的性能比 Lock 要好但是在 Java 5 之后Lock 的性能得到了大幅度提升特别是在高并发的情况下Lock 的性能优势更加明显。
4、可中断性synchronized 是不可中断的锁一旦一个线程进入了一个 synchronized 块其他线程就必须等待该线程执行完毕并释放锁才能继续执行。而 Lock 是可中断的锁即一个线程在等待锁的时候可以通过调用 lockInterruptibly() 方法来中断等待。
5、条件变量Lock 提供了条件变量可以使用 Condition 接口来实现等待/通知模型而 synchronized 没有提供对应的机制。
6、灵活性Lock 的灵活性比 synchronized 更高例如可以选择公平锁或非公平锁可以设置超时时间等。
总之虽然 synchronized 和 Lock 都可以用于实现线程同步但是它们的使用方法和特点有所不同需要根据具体的需求来选择合适的机制。在 JDK 5 之后由于 Lock 的性能提升和灵活性越来越多的开发者使用 Lock 来实现线程同步。