12
votes

Verrouillage de fichier Java

J'ai plusieurs threads (dont certains sont générés par le processus x, d'autres par processus Y, et ctera ), et chaque fil doit écrire dans un fichier myfile . Toutefois, si thread t1 commence à écrire sur myfile d'abord, alors, lorsque thread T2 commence à écrire, il doit attendre T1 < / Code> Pour relâchez le fichier , de sorte qu'il puisse lire le contenu écrit dans thread t1 . En d'autres termes, chaque thread aurait une méthode finalizethread , comme: xxx

Ma question est la suivante: comment puis-je accomplir le verrouillé_section dans le code ci-dessus? Je cherchais dans la classe filelock , mais il est indiqué dans le Javadoc que les verrouillages de fichiers "sont conservés pour le compte de la machine virtuelle Java. Ils ne conviennent pas pour contrôler l'accès à un fichier par threads multiples dans la même machine virtuelle. ".


2 commentaires

Êtes-vous sûr de vouloir vraiment finaliser () la méthode?


Non, le nom de la méthode n'est pas réellement finaliser . C'est une méthode / rappel appelé après le thread (en réalité, un ensemble de fils, mais cela n'est pas pertinent que le cas) est fini avec son travail, car je n'utilise pas les fils d'API standard Java Concurrency. Je vais le renommer pour éviter les confusions avec objet # finaliser .


3 Réponses :


0
votes

Vous voudrez synchroniser sur certains objets. Par exemple: xxx


5 commentaires

Bonjour Anon., Merci pour votre commentaire. Cependant, je ne peux pas faire cela, car ces threads sont engendrés par différents processus, et je ne peux pas partager cet objet parmi tous les threads, d'où la nécessité d'une autre approche. Ce ne sont pas non plus la standard Java Concurrence. * threads, mais des threads créés par une API Oracle.


S'ils sont des processus différents (et donc des VMS séparés), vous pouvez simplement utiliser la classe filelock .


Oui, mais certains sont générés par le même processus. Mais oui, une stratégie hybride fonctionnerait peut-être. Merci.


@Stephen: Ce n'est pas ce que dit la documentation.


@Stephenc, et comment le ferait-il?



14
votes

Si le fichier est accessible uniquement à partir de votre programme, l'objet de verrouillage synchronisé est correct. Mais si vous souhaitez protéger le fichier d'être modifié par d'autres programmes lorsque vous y travaillez, vous pouvez utiliser les fonctions de verrouillage du fichier de Java dans java.nio.channel.filelock ( Exemple ). Comme le dit le texte indique que sur certains systèmes d'exploitation, les programmes peuvent toujours modifier des fichiers s'ils ne vérifient pas un verrou de fichier existant.


6 commentaires

Merci pour les commentaires. Oui, il n'est accessible que par mon programme et chaque thread sera / peut vérifier l'existence d'une serrure avant de procéder. Le problème est que l'API que j'utilise peut engendrer des threads de plusieurs processus différents et des threads de la même procédure, et je crains que des problèmes soient liés à cela, depuis le filelock Javadoc le mentionne.


Peut-être que je suis mal compris quelque chose, mais que voulez-vous dire que vous avez des threads engendré par différents processus? Un processus a son propre espace d'adresses et tous les threads qu'il crée partagé cet espace d'adressage. Avez-vous de multiples processus à accumuler plusieurs threads multiples qui peuvent essayer d'écrire sur le même fichier?


Le Javadoc dit: "Les serrures de fichier sont conservées pour le compte de l'ensemble de la machine virtuelle Java. Ils ne conviennent pas à la commande d'accès à un fichier par plusieurs threads dans la même machine virtuelle. Les objets de verrouillage du fichier sont sûrs pour une utilisation par plusieurs threads simultanés. " Les deux dernières phrases ne sont-elles pas exclusives mutuellement exclusives? Je pense que quelqu'un devra examiner le code source ... Dans le paragraphe suivant, il est indiqué "Cette API de verrouillage de fichier est destinée à mapper directement sur la facilité de verrouillage natif du système d'exploitation sous-jacent." Donc, il devrait Travailler comme FLOCK (Linux) ou LockfileEx (Windows).


Non, ça a du sens. En ce qui concerne ces deux phrases, le premier dit "N'utilisez pas de verrouillage de fichier pour contrôler l'accès à un fichier entre les threads" et la seconde dit "Les threads multiples peuvent utiliser le même verrou de fichier aussi longtemps qu'ils sont conscients qu'ils sont conscients qu'ils avoir le même verrouillage de fichier "


@DANBEN: D'accord, merci pour la circonscription, maintenant ça a du sens :)


Selon votre cas d'utilisation, en utilisant filechannel.trylock peut être beaucoup mieux que d'utiliser filechannel.lock , puisque trylock ne bloque pas. Si vous utilisez filechannel.lock , cette méthode attendra que le verrou soit soulevé par un autre fil (ou processus), puis il procédera. Test sur Oracle Java 7 montre qu'il s'agit d'une opération ininterruptible même si elle déclare qu'il lance filelockinterruptionException .



2
votes

Au lieu de partager une serrure, vous pourriez peut-être avoir un processus distinct responsable de la maintenance d'un verrouillage du fichier. Pour commencer votre étape de lecture / modification / écriture, un thread devrait demander à ce processus central pour la serrure via HTTP, ou de la messagerie, ou de ce que vous aimez. Si la demande est refusée, le fil allait dormir, se réveiller et réessayer. Sinon, le fil aurait lu / modifier / écrire, puis indiquer au processus de verrouillage qu'il libère le verrou.


1 commentaires

Si vous allez utiliser un processus central, il est probablement préférable que ce processus gère la lecture / l'écriture elle-même, de sorte que vous n'avez pas à vous soucier de ce qui se passe lorsqu'un fil meurt après avoir été émis le verrou (e-ce que vous faites, mais c'est moins compliqué).