2013-06-13 5 views
0

J'ai une méthode commune qui est accessible par plusieurs threads,Comment savoir un verrou a été acquis

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

Parfois, le fileName peut-être même dans deux ou plusieurs fils et je reçois une exception lorsque j'utilise trylock() ou verrouiller(). Comment puis-je savoir si un verrou a déjà été acquis?

Mise à jour:

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

je reçois une 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) 
+2

Est-ce que 'tryLock()' ne retourne pas 'null' s'il ne peut pas acquérir le verrou? –

+0

@SotiriosDelimanolis - Mauvais 'tryLock()'. Voir l'API ['FileChannel'] (http://docs.oracle.com/javase/6/docs/api/java/nio/channels/FileChannel.html#tryLock()). –

+0

@RichardJPLeGuen Sortez d'ici! –

Répondre

2

Comment puis-je savoir si un verrou a déjà été acquis?

La meilleure réponse est d'utiliser fc.tryLock();. Cependant, il ne doit pas pas jeter une exception. Il renverra null si le verrou ne peut pas être acquis. C'est le meilleur moyen de voir si le verrou n'est pas verrouillé.

Pour citer le javadocs for FileChannel.tryLock():

Cette méthode ne bloque pas. Une invocation revient toujours immédiatement, soit en ayant acquis un verrou sur la région demandée, soit en ayant omis de le faire. S'il ne parvient pas à acquérir un verrou parce qu'un verrou chevauchant est détenu par un autre programme, alors il renvoie null. S'il ne parvient pas à acquérir un verrou pour une autre raison, une exception appropriée est levée.

1

Droite. Donc, il se comporte comme prévu, parce que l'utilisateur essaie d'acquérir le verrou deux fois dans un seul programme (renvoie null si un autre programme a le verrou, tous les threads sont dans un programme). Je n'aimerais jamais recommander d'attraper cette exception comme un moyen de savoir si un verrou est déjà en place. Il semble que vous feriez mieux de configurer une autre variable interne dans votre programme pour maintenir l'état de verrouillage. Ou attraper l'exception et l'utiliser pour signifier que "le verrou est déjà acquis dans ce programme".

Questions connexes