Java的FileChannel 类 tryLock() 方法及示例
在多线程程序的情况下,多个线程同时执行,我们需要获取和释放锁以保持进程之间的同步。 Java 的FileChannel 类还提供了一种称为trylock()的方法,用于获取指定文件的锁定。此方法用于获取文件任何区域的锁定,在方法的参数中指定。
锁可能是一种比标准同步块更灵活和复杂的线程同步机制。锁可以是控制多个线程访问共享资源的工具。通常,锁提供对共享资源的独占访问:一次只有一个线程可以获取锁,并且每个人访问共享资源都需要先获取锁。但是,某些锁可能允许并发访问共享资源,例如 ReadWriteLock 的读锁。
这里的输出是FileLock 类的对象,它提到了应用的锁,如果没有应用锁(可能是由于其他一些进程正在持有或写入文件的原因)那么这个方法将返回 null。 Position 变量指定文件的标记,从哪里获取锁,并且范围(要获取锁的范围)由 'size' 变量给出。如果在第二个参数的位置没有提及任何内容,则默认采用 Long.MAX_VALUE 的大小。 “shared”布尔变量告诉锁是否是共享的。如果它是假的,那么锁是一个独占锁,否则在其他进程之间共享。这些是同步方法的一些基础知识。它的默认值被认为是假的。
这种方法的主要优点是它永远不会被阻塞。调用后,如果文件由另一个进程处理或引发异常,它要么返回获取的锁,要么返回 null。这个方法一般不同于同一个类的 lock() 方法,在同步过程中必须等待很长时间才能访问文件或资源并获取锁,但是这个方法永远不会依次等待它会返回空值或例外。
语法:方法声明
public abstract FileLock tryLock(long position, long size, boolean shared) throws IOException
例子
Java
// Java Program to illustrate FileChannel Class
// tryLock() method
// Importing libraries
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
// save the file named as GFG.java
public class GFG extends Thread {
// content to be written in the file.
String input
= "geeks for geeks is a learning portal for computer sciences.";
ByteBuffer buf = ByteBuffer.wrap(input.getBytes());
// path of the file
String fp = "gfg.txt";
// file channel class object
Path pt = Paths.get(fp);
public void run()
{
try {
// the thread says if file is opened.
FileChannel fc = FileChannel.open(
pt, StandardOpenOption.WRITE,
StandardOpenOption.APPEND);
System.out.println(
Thread.currentThread().getId()
+ "says:File channel is opened for writing");
// trying lock
fc.tryLock(0L, Long.MAX_VALUE, false);
System.out.println(
Thread.currentThread().getId()
+ "says:acquiring lock");
// writing
fc.write(buf);
// release the Lock after writing
System.out.print(Thread.currentThread().getId()
+ "says:");
System.out.println(
"writing is done, closing the file");
// Closing the file connections
fc.close();
}
// Catch block to handle the exception
catch (Exception e) {
// Getting and printing current threads
System.out.println(
Thread.currentThread().getId()
+ "says: Exception" + e);
}
// Here, one file raises exception since the file
// is being written by another thread.
}
// Main driver method
public static void main(String[] args) throws Exception
{
// Creating an object in the main() method
GFG g1 = new GFG();
GFG g2 = new GFG();
// Calling start() methods over the objects
g1.start();
g2.start();
// Here Two thread in concurrency
// are trying to access the file
}
}
输出:
输出说明:
我们正在创建两个线程,它们将尝试访问该文件并对其执行写操作。因为为了保持同步,我们使用了trylock()方法。当其中一个线程获取锁并对文件执行操作时,如果第二个线程调用要获取的锁,则该方法会引发异常,因为该文件不可自由获取。在上面的代码中,我们显式地获取了整个文件的锁。如果需要,我们可以更改必须获取锁的文件部分的大小。