2011-12-17 5 views
1

Je travaille sur un grand devoir qui implémente l'utilisation de Threads et de méthodes synchronisées. Je n'ai jamais travaillé avec Threads auparavant, donc c'est un peu déroutant. Comme les devoirs sont trop gros, j'ai décidé d'essayer d'abord avec un exemple simple. Ainsi, dans cet exemple, j'ai 4 classes:Java, travailler avec des threads

  • Food, un objet qui est seulement stocké.
  • Worker qui "rassemble" les aliments et les stocke dans le stockage. Il a des heures de travail limitées, ce qui diminue chaque fois qu'il "rassemble" de la nourriture.
  • Storage qui sert de récipient pour la nourriture et a une capacité limitée.
  • Trash - est pas grand-chose d'un objet, il est juste utilisé pour supprimer des éléments de stockage

Par définition, Worker doit être un fil. Sa méthode run() contient une boucle qui permettra au travailleur de rassembler des aliments (créer de nouvelles instances de nourriture) et de les stocker dans une pile en Storage. Chaque rassemblement réussi diminue les heures de travail. Cette boucle va se répéter jusqu'à ce que les heures de travail soient égales à 0. Maintenant, c'est là que je ne comprends pas comment faire attendre un thread. Disons, un travailleur a 15 heures et la capacité de stockage est de 10. Donc, le travailleur devrait ajouter 10 nouveaux aliments dans le stockage, maximiser sa capacité, et attendre un événement (externe) pour augmenter la capacité ou retirer des aliments du stockage donc il peut continuer à "rassembler" la nourriture et l'ajouter au stockage. Voici mon code actuel:

import java.util.*; 

class testSync { 

    public static void main(String[] args) { 
     /** Create a storage **/ 
     Storage storage = new Storage(); 
     /** Assign a worker to this storage **/ 
     Worker worker = new Worker(storage); 
     /** Create a trash can **/ 
     Trash trash = new Trash(storage); 

     /** Start new thread **/ 
     new Thread(worker).start(); 

     /** The thread should work until the maximum capacity of the storage has been reached **/ 

     /** Throw item so that further items can be added **/ 
     trash.throwItem(); 

    } 
} 

/** WORKER CLASS **/ 
class Worker implements Runnable { 
    int work = 15; 
    Storage storage; 
    public Worker(Storage s) { 
     storage = s; 
    } 
    /** Run this method until working hours equal to zero **/ 
    public void run() { 
     while (work > 0) { 
      System.out.println(work); 
      storage.store(new Food()); 
      work--; 
      /** In case the capacity has been maxed out, wait for some event which will remove food items from the storage **/ 
      if (!storage.hasSpace()) { 
       // WAIT FOR THE STORAGE TO BE EMPTIED AND THEN CONTINUE ADDING 
      } 
     } 
    } 
} 
/** TRASH CLASS **/ 
class Trash { 

    Storage storage; 

    public Trash(Storage s) { 
     storage = s; 
    } 
    /** Remove one item from the storage **/ 
    public void throwItem() { 
     storage.load(); 
    } 
} 

/** FOOD CLASS **/ 
class Food { 
    public Food() {} 
} 

/** STORAGE CLASS **/ 
class Storage { 

    private int cap = 10; 
    private Stack<Food> container = new Stack<Food>(); 

    public Storage() {} 
    /** Check to see if there's any free space **/ 
    public boolean hasSpace() { 
     if (container.size() < cap) 
      return true; 
     else 
      return false; 
    } 
    /** If capacity allows, add one an item to the storage **/ 
    public void store(Food food) { 
     if (hasSpace()) { 
      container.push(food); 
     } 
    } 
    /** Remove one item from the fridge **/ 
    public Food load() { 
     return container.pop(); 
    } 
} 
+0

Quelque chose manque: qui enlève la nourriture du stockage? Quand le retire-t-il? –

+0

Dans cet exemple, une poubelle, mais dans mes devoirs, un autre type de travailleur qui est également utilisé comme un fil. – vedran

Répondre

3

Créez une méthode synchronisée sur le stockage qui renvoie true à l'acceptation du stockage. Quelque chose comme ça ...

public synchronized boolean store (int num) {  
    if ( items < capacity) { 
     items ++; 
     return true; 
    } 
    return false; 
} 
+1

Je suppose que vous voulez dire "retour faux" à la dernière ligne –

+0

Yeh excuses. Corrigé maintenant. –

3

Jetez un oeil à la classe BlockingQueue - si vous implémentez correctement, vous pouvez utiliser quelque chose comme ça que le travailleur peut faire appel, mais il ne reviendra pas jusqu'à ce que la file d'attente (stockage) a de la place pour l'objet.

+0

Merci, mais je dois pouvoir prendre et ajouter à la file d'attente chaque fois que le programme en a besoin. – vedran

+2

Non, vous ne le faites pas. Vous voulez prendre et ajouter à la file d'attente chaque fois que c'est le bon moment pour le faire, selon la description de vos devoirs. Et la file d'attente de blocage garantira exactement cela. (À condition qu'il s'agisse d'une file d'attente de blocage * délimitée *, afin de fournir une synchronisation non seulement pour l'extrémité de vidage, mais aussi pour l'extrémité de remplissage.) –

+0

Exactement. Vous venez de dire: "Donc, le travailleur devrait ajouter 10 nouveaux aliments dans le stockage, maximiser sa capacité, et attendre un événement (externe) pour augmenter la capacité ou retirer des aliments du stockage afin qu'il puisse continuer à" rassembler "le nourriture et l'ajouter au stockage. " – Kylar