1

Une partie de code multithread accède de façon asynchrone à une ressource (par exemple: un système de fichiers).Utilisation de variables de code et de condition multithread

Pour ce faire, j'utiliserai des variables de condition. Supposons que le FileSystem est une interface comme:

class FileSystem { 
    // sends a read request to the fileSystem 
    read(String fileName) { 
     // ... 
     // upon completion, execute a callback 
     callback(returnCode, buffer); 
    } 
} 

J'ai maintenant une application qui accède au FileSystem. Supposons que je puisse émettre plusieurs lectures via une méthode readFile(). L'opération doit écrire des données dans le tampon d'octets qui lui est transmis.

// constructor 
public Test() { 
    FileSystem disk = ... 
    boolean readReady = ... 
    Lock lock = ... 

    Condition responseReady = lock.newCondition(); 
} 

// the read file method in quesiton 
public void readFile(String file) { 
    try { 
     lock.lock(); // lets imagine this operation needs a lock 

     // this operation may take a while to complete; 
     // but the method should return immediately 
     disk.read(file); 

     while (!readReady) { // <<< THIS 
      responseReady.awaitUninterruptibly(); 
     } 
    } 
    finally { 
     lock.unlock(); 
    } 
} 

public void callback(int returnCode, byte[] buffer) { 
    // other code snipped... 

    readReady = true; // <<< AND THIS 
    responseReady.signal(); 
} 

Est-ce la bonne façon d'utiliser les variables de condition? Est-ce que readFile() reviendra immédiatement?

(Je sais qu'il ya un certain sillyness à l'aide de verrous pour les lectures, mais l'écriture dans un fichier est également une option.)

Répondre

1

Il y a beaucoup manque à votre question (pas de mention spécifique de threads) mais je vais essayer de répondre de toute façon. Ni le verrou ni les variables conditionnelles ne vous permettent d'utiliser les fonctions d'arrière-plan. Elles sont simplement utilisées pour qu'un thread attende les signaux d'autres threads. Bien que vous ne le mentionniez pas, la méthode disk.read(file) peut générer un thread pour faire l'E/S, puis revenir immédiatement mais l'appelant va s'asseoir dans la boucle readReady de toute façon, ce qui semble inutile. Si l'appelant doit attendre, il peut effectuer lui-même l'E/S elle-même.

Un meilleur modèle pourrait être d'utiliser quelque chose comme le service Java 5 Huissiers:

ExecutorService pool = Executors.newFixedThreadPool(int numThreads); 

Vous pouvez ensuite appeler pool.submit(Callable) qui présentera le travail à effectuer en arrière-plan dans un autre thread (lorsque la piscine à côté a un disponible). Submit renvoie un Future que l'appelant peut utiliser pour déterminer si la tâche d'arrière-plan est terminée. Il peut également renvoyer un objet résultat. Les classes simultanées prennent en charge le verrouillage et le signal conditionnel/attente logique pour vous.

Espérons que cela aide.

p.s. En outre, vous devez rendre readReady volatile car il n'est pas synchronisé.