Reputation: 5040
I have a common method which is accessed by multiple threads,
public void m(String fileName)
{
FileOutputStream fos= new FileOutputStream(fileName);
FileChannel fc = fos.getChannel();
fc.tryLock();
....
Sometimes the fileName might be same in two or more threads and I get an exception when I use tryLock() or lock(). How can I know if a lock has already been acquired?
Update:
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();
}
}
I get an exception:
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)
Upvotes: 0
Views: 1444
Reputation: 3086
Right. So it's behaving as expected, because the user is trying to acquire the lock twice within a single program (returns null if another program has the lock, all threads are within one program). I'd hate to ever recommending catching that exception as a way to tell if a lock's already in place. Sounds like you may be best to set up another internal variable within your program to hold the lock state. Or catch the exception and use that to mean "lock is already acquired within this program".
Upvotes: 1
Reputation: 116858
How can I know if a lock has already been acquired?
The best answer is to use fc.tryLock();
. However, it should not throw an exception. It will return null
if the lock cannot be acquired. That's the best way to see if the lock is not locked.
To quote from the javadocs for FileChannel.tryLock():
This method does not block. An invocation always returns immediately, either having acquired a lock on the requested region or having failed to do so. If it fails to acquire a lock because an overlapping lock is held by another program then it returns null. If it fails to acquire a lock for any other reason then an appropriate exception is thrown.
Upvotes: 2