If THen ELse…

journal de bord d'un aspirant codeur

J’ai écrit en début d’année un verrou permettant de contourner les deadlocks en java.
Avant d’en expliquer le fonctionnement, un rapide petit rappel sur ce qu’est une situation de deadlock:

schema 1

Etape 1: le premier thread acquiert le verrou numéro 1.
Etape 2: le second thread acquiert le verrou numéro 2.
Etape 3: le premier thread cherche maintenant à acquérir le deuxième verrou. Il doit donc attendre que le deuxième thread n’en soit plus propriétaire.
Etape 4: le deuxième thread cherche maintenant à acquérir le premier verrou. Il doit donc attendre que le premier thread n’en soit plus propriétaire.

Cette situation est une situation d’inter-blocage: chacun des deux threads attend que l’autre libère le verrou qu’il possède, le programme est donc bloqué.

Détection d’une situation d’interblocage
Pour écrire un algorithme permettant de résoudre ce problème, il faut commencer par savoir le détecter. Ce n’est pas très évident avec cet exemple, alors voyons un peu une situation d’inter-blocage impliquant 4 threads et 4 verrous:

schema 2

On voit désormais qu’une situation d’inter-blocage se manifeste par la création d’un cycle: en partant d’un thread quelconque et en allant de verrou en thread et de thread en verrou, on retombe sur le thread de départ.
Cette remarque faîte, il devient relativement aisé de concevoir un algorithme qui détecte une telle situation. En voici un exemple en pseudo-code:


pour chaque verrou
     si le propriétaire du verrou est le thread qui lance la vérification
          alors pour chaque threads demandeurs de ce verrou
               if(isDeadLock(demandeur))
                    un cycle a été détecté


isDeadLock(thread):
     si le thread passé en paramètre est le thread courant
          un cycle a été détecté
     sinon
          pour chaque verrou dont le thread est propriétaire
               pour chaque demandeur de ces verrous
                         isDeadLock(demandeur)

Intégration de l’algorithme dans notre verrou
Le fonctionnement interne d’un verrou est le suivant:

schema 3

Il reste donc à intégrer notre algorithme de détection de cycle au coeur de ce système et effectuer les opérations nécessaires selon que la détection soit positive (abandon au moyen d’une exception) ou non (poursuite de l’attente).

schema 4

Durant la période d’attente, chaque thread devra donc régulièrement s’assurer qu’un cycle n’a pas été constitué; cela n’implique pas nécessairement une attente active puisqu’il est possible de donner en paramètre de la fonction wait un délais au delà duquel le thread devra se réveiller s’il n’a pas été notifié.

Une difficulté que l’on rencontre immédiatement avec Flex lorsqu’on souhaite afficher de manière dynamique des images lourdes concerne la gestion du cache. En effet, le comportement par défaut du flashplayer lorsque votre application s’apprête à afficher une image qui a déjà été téléchargée consiste à… la télécharger de nouveau.

Une solution pour résoudre ce problème (et donc les temps de chargement répétés qu’il implique) a été proposée sur le blog Miscellanea. L’idée est la suivante: utiliser une classe static (ImageCache) dont le rôle est de conserver les objets BitmapData relatifs aux images qui ont déjà été chargées, et étendre la classe Image afin de vérifier automatiquement lors de l’affectation de l’attribut source si ses données sont déjà présentes ou non dans ImageCached. Une solution à la fois simple et astucieuse.

Pour une application AIR destinée à uploader des données sur un serveur, il peut être souhaitable d’indiquer à l’utilisateur, à l’aide d’un TextInput par exemple, le nom et l’emplacement du fichier qu’il s’apprête à envoyer.
Problème: FileReference ne possède pas d’attribut contenant cette deuxième information. La solution: utiliser la classe File, héritant de FileReference, et son attribut nativePath.

Source: http://blog.arnomanders.nl/index.php/archives/get-full-file-path-in-air/

Inutile de présenter le fonctionnement de FileReference, suffisamment d’informations circulent sur le web à ce sujet. En revanche une chose est rarement précisée: pour qu’une opération d’upload ou de download aille jusqu’à son terme, il faut que la variable de type FileReference utilisée soit globale.
On pourrait penser que, quand bien même, la tâche devrait logiquement se poursuivre en arrière plan après le retour de la fonction qui a servi à créer l’objet, et bien non. Pire: aucun indice ne vous sera donné pendant la compilation ou l’exécution pour indiquer un problème et l’opération ne produira aucun résultat.

Je viens de passer plusieurs heures à essayer de dimensionner correctement un module… Tout ce temps perdu pour réaliser quelque chose d’aussi trivial, c’est légèrement énervant. Mais voilà, après pas mal de tâtonnements j’ai fini par comprendre que lorsqu’on crée un nouveau module, les paramètres width et height de la balise mx:Module ne sont pas suffisants.

<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%">

En fait, il est également nécessaire de préciser la largeur et la hauteur que vous attendez dans le code de l’application:

<mx:ModuleLoader url="Mod.swf" id="moduleActif" width="100%" height="100%" / >

Dans la rubrique « on ne m’avait rien dit », je viens d’apprendre en faisant un petit tour sur la doc de sun que l’usage de la classe StringTokenizer est déconseillé depuis la version 1.4.2 du JDK.

StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.

C’est plutôt une bonne chose dans la mesure ou StringTokenizer ne prend pas en compte les séparateurs de plus d’un caractère et est assez lourd à utiliser. Ce qui est étonnant en revanche c’est que:

  • elle ne soit pas pour autant dépréciée.
  • on continu de nous l’enseigner à la fac (joke inside)

Cela faisait un petit moment que la création d’un blog me tentait, c’est désormais chose faite.
Mais un blog pour qui et pour quoi?

  • Avant tout pour disposer d’une plate-forme qui me permettra de diffuser les quelques bizarreries qui traînent dans ma malle à applications (histoire de pas avoir codé tout ça en vain, même si je ne me fais pas d’illusions ^^).
  • Pour disposer également d’une vitrine qui permettra aux webmasters intéressés par mes compétences de me contacter (voir les pages présentation, compétences et réalisations pour en savoir plus).
  • Pour témoigner, enfin, des difficultés auxquelles je dois parfois faire face avec tel ou tel langage, en espérant que cela puisse être utile à d’autres.