2013-06-13 2 views
0

У меня есть общий метод, который доступен несколько потоков,Как знать, замок был приобретен

 public void m(String fileName) 
    {   
     FileOutputStream fos= new FileOutputStream(fileName); 
     FileChannel fc = fos.getChannel(); 
     fc.tryLock(); 
     .... 

Иногда имя_файл может быть тем же самым в двух или более потоках, и я получаю исключение, когда я использую tryLock() или lock(). Как я могу узнать, был ли уже установлен замок?

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(); 
    } 
} 

я получаю исключение:

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) 
+2

Не 'tryLock()' return 'null', если он не может получить блокировку? –

+0

@SotiriosDelimanolis - Неверно 'tryLock()'. См. API ['FileChannel'] (http://docs.oracle.com/javase/6/docs/api/java/nio/channels/FileChannel.html#tryLock()). –

+0

@RichardJPLeGuen Получите отсюда! –

ответ

2

Как я могу знать, если блокировка уже приобретена?

Лучший ответ - использовать fc.tryLock();. Однако это должно быть не исключение. Он будет возвращать null, если блокировка не может быть приобретена. Это лучший способ проверить, заблокирован ли замок.

Цитата из javadocs for FileChannel.tryLock():

Этот метод не блокирует. Вызов всегда возвращается немедленно, либо получив блокировку в запрошенном регионе, либо не выполнив этого. Если он не может получить блокировку, потому что перекрывающая блокировка удерживается другой программой, тогда возвращает нуль. Если ему не удается получить блокировку по любой другой причине, то создается соответствующее исключение.

1

Право. Таким образом, он ведет себя так, как ожидалось, потому что пользователь пытается дважды получить блокировку в одной программе (возвращает null, если еще одна программа имеет блокировку, все потоки в одной программе). Мне бы не хотелось рекомендовать это исключение, чтобы узнать, уже заблокирован ли замок. Похоже, вам лучше всего настроить другую внутреннюю переменную в вашей программе, чтобы удерживать состояние блокировки. Или поймайте исключение и используйте это, чтобы означать, что «блокировка уже получена в этой программе».

Смежные вопросы