J'ai une application swing assez lente pour démarrer car elle doit charger mille images dans l'interface graphique. Il faut 10 secondes pour démarrer.
Il s'agit d'une seule application de thread, comment pourrais-je coder multithread pour accélérer la tâche? Le code suivant est dans A pour boucle de 1000 itérations. P> Les images sont chargées et placées dans une boîte séquentiellement. J'ai deux difficultés si je veux le faire multithread p> merci. p> p>
3 Réponses :
Comment une valeur de retour de thread est-elle au parent p>
Utilisez un mécanisme de rappel. Pour une balançoire qui signifierait à l'aide d'un swingworker et signifierait l'achèvement de l'arrivée de fil de fil, que ce soit dans la méthode
faite () du travailleur () CODE> ou en ajoutant un PropertyChangelistener au travailleur, écoutant la propriété "State" du travailleur, pour le moment où Il passe à
swingworker.statevalue.done code> p>
Comment réaliser des rappels non bloquants qui ajoutent l'image à la boîte séquentiellement p> blockQuote>
Le swingworker a une paire de méthodes de publication / processus permettant d'envoyer des données séquentielles à partir du thread de fond via la méthode de publication, puis de gérer les données séquentielles sur le thread de l'événement dans la méthode du processus. Cela nécessite l'utilisation d'un
swingworker
code> ou swingworker
code> ou quelque chose de similaire, le paramètre 2e générique indiquant le type d'objet envoyé via ce mécanisme. p> Par exemple: p>
xxx pré> et pour l'utiliser dans une interface graphique: p>
xxx pré> pour plus SUR SWING CULCULENCY, veuillez consulter Leçon: Concurrence dans Swing P> blockQuote>
Merci! Je regarderais certainement ça.
Multithreading accélérera l'application, mais je pense que faire une charge paresseuse est une meilleure approche (vous pouvez faire les deux). Vous ne pouvez pas afficher toutes ces images en même temps, vous vous suggérez donc de charger les images qui seront visibles au début et après cette charge, si nécessaire, cela augmentera votre performance et utilisez moins de mémoire / de ressource. p>
Si vous voulez vraiment charger les 1000 images:
Il suffit d'utiliser un fil d'arrière-plan, de sorte que vous ne ralentissez pas le fil de boucle d'événement balançoire principal. P>
Créer une coutume Classe qui implémente runnable et a des références à tout le contexte pour faire le travail. Comme: p> Démarrez ensuite le processus de chargement lors de votre initialisation de votre application, en faisant passer l'exécution d'un nouveau fil, puis en commençant le fil. Comme: p>
Pourquoi pensez-vous que le filetage multi-threading accélérerait-il?
Notez que le filetage d'arrière-plan empêcherait la congélation de l'interface graphique si elle est bien faite, mais toujours le goulot d'étranglement est le code de lecture en lecture, quel filetage ne serait probablement pas amélioré. Notez également que vous utiliseriez probablement un appel de rappel pour informer l'interface graphique lorsque le thread est terminé, par exemple via une méthode
effectuée par Swingworker (code> ou un
PropertyChangelistener code> ajouté à la Fil du travailleur, celui qui écoute pour l'achèvement des travailleurs.
Les 1000 images sont-elles affichées dans l'interface graphique en même temps? Sinon, alors ne chargez que celles qui affichent actuellement et chargent le reste sur la demande.
Pour ajouter des images séquentiellement, utilisez la paire de méthodes de publication / processus de Swingworker, conformément au didacticiel standard. Cela signifierait d'utiliser un
swingworker code> Signature générique ou quelque chose de similaire (c'est-à-dire bufferedimage au lieu de l'image, si désiré).
@DontMoDluchbuttittingbetter Pourquoi penseriez-vous que cela n'accorderait pas? Le code ci-dessus dans une boucle avec 1k ne produira sûrement pas 100% d'utilisation du disque (ou quelles que soient les images sont en lecture). Et les images sont probablement décodées pour une utilisation interne qui bénéficie également d'un parallélisme.
@CMOETZING: Cela dépend de l'endroit où réside le goulot d'étranglement. Je pose que la lecture physique est beaucoup plus lente que le décodage, ce qui n'est pas accéléré par une filetage.
@CMOETZING: Là encore, Cette réponse suggère que la multi-threading peut aider.
La vraie réponse est la suivante: identifier le cou de la bouteille premier b>. Mesurez ce qui se passe et où le temps est passé.
@Ghostcat généralement vrai, mais probablement non pertinent dans ce cas: lorsqu'une application Swing chargea 1000 images au démarrage et prend 10 secondes pour commencer, on peut assumer la causalité ici. La question manque toujours de détails nécessaires pour suggérer la solution de contournement la plus appropriée, mais certaines des réponses montrent déjà des approches imaginables.
@Ghostcat Un point que vous avez peut-être réaffirmé à définitive est pertinent B>, cependant: si le chargement des images peut être accéléré via Multhreading B> doit être évalué. Si les images sont lues à partir d'un disque dur, l'accès à plusieurs threads peut en réalité être plus lent i> que l'accès séquentiel. (Ceci est indépendant de l'utilisation d'un fil d'arrière-plan pour empêcher l'interface utilisateur de bloquer)
Notez que
Toolkit.GetImage (chaîne) code>
chargera des images de manière asynchrone. L'application. peut charger et afficher pendant que les images sont toujours en cours de chargement.Bonjour, j'ai identifié le goulot d'étranglement est l'image en cours de chargement, car la suppression du code de chargement de l'image a immédiatement fait la charge de l'interface graphique.
Pour souligner Andrew Thompson's Point: Remplacez la première ligne de votre code avec
imageicon icon = Nouvelle imageicon (Toolkit.getDeFaultToolkit (). GetImage (CoverFile.tos Tring ())); Code>. Les images seront chargées en arrière-plan; Pas besoin de vous de créer vos propres threads.