我有一个可以被多个线程访问的常用方法
public void m(String fileName)
{
FileOutputStream fos= new FileOutputStream(fileName);
FileChannel fc = fos.getChannel();
fc.tryLock();
....
有时两个或多个线程中的fileName可能相同,当我使用tryLock()或lock()时,我得到一个异常。我如何知道是否已获得锁?
更新:
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
class A implements Runnable{
@Override
public void run()
{
try
{
FileOutputStream fos= new FileOutputStream("file.2txt");
FileChannel fc = fos.getChannel();
fc.tryLock();
Thread.sleep(4000);
fc.close();
System.out.println("done");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public class Test
{
public static void main(String[] args) throws Exception
{
new Thread(new A()).start();
Thread.sleep(2000);
new Thread(new A()).start();
}
}
我得到一个例外:
java.nio.channels.OverlappingFileLockException
at sun.nio.ch.FileChannelImpl$SharedFileLockTable.checkList(Unknown Source)
at sun.nio.ch.FileChannelImpl$SharedFileLockTable.add(Unknown Source)
at sun.nio.ch.FileChannelImpl.tryLock(Unknown Source)
at java.nio.channels.FileChannel.tryLock(Unknown Source)
at run.A.run(Test.java:14)
at java.lang.Thread.run(Unknown Source)
答案 0 :(得分:2)
我如何知道是否已获得锁定?
最佳答案是使用fc.tryLock();
。但是,它应该不抛出异常。如果无法获取锁,它将返回null
。这是查看锁是否未锁定的最佳方式。
引用javadocs for FileChannel.tryLock():
此方法不会阻止。调用始终立即返回,要么已获取所请求区域的锁定,要么未能执行此操作。如果由于另一个程序持有重叠锁而无法获取锁定,则将返回null 。如果由于任何其他原因而无法获取锁定,则会抛出相应的异常。
答案 1 :(得分:1)
右。所以它的行为符合预期,因为用户试图在单个程序中获取锁两次(如果另一个程序具有锁,则返回null,所有线程都在一个程序中)。我不愿意建议捕获该异常,以此来判断锁是否已经到位。听起来你可能最好在程序中设置另一个内部变量来保持锁定状态。或者捕获异常并使用它来表示“已在此程序中获取锁定”。