Visualizzazione dei risultati da 1 a 7 su 7

Hybrid View

  1. #1
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Samaritan Visualizza il messaggio
    non ho quindi utilizzato gli oggetti di Swing per eseguire l'upload dei files in un altro thread come SwingUtilities.invokeLater o SwingWorker e sincronizzare il tutto con l'EDT
    invokeLater non sarebbe stato comunque utile nel tuo caso. invokeLater fa eseguire qualcosa "appena possibile" ma comunque nel contesto del EDT.
    SwingWorker invece fa eseguire quel qualcosa in un thread separato ma facilita la interazione con la GUI (nel EDT) nel caso il "lavoro" debba fare, di tanto in tanto, qualche aggiornamento sulla interfaccia utente.

    Quote Originariamente inviata da Samaritan Visualizza il messaggio
    visto che questo processo che genera ed invia i files al server non interferisce minimamente con ciò che viene mostrato nella gui.
    Ho semplicemente provveduto a creare un nuovo Thread a cui ho passato un oggetto Runnable nel cui metodo run() ho fatto tutto.
    Poi ho settato questo thread come daemon thread e l'ho avviato con start().

    Per invocare l'eseguibile esterno ho ovviamente utilizzato l'oggetto Runtime di java con un normale Runtime.exec(...) all'interno del metodo run() del Runnable passato al Thread.
    Corretto sì, lo è. Si potrebbe far notare una cosa però. Il exec() avvia il processo in modo asincrono, ovvero exec è praticamente immediato. Se non devi attendere la fine del processo per prendere il suo exit-code e non devi fornire al processo dati continui su standard-input oppure leggere i suoi standard-output/error, allora il nuovo thread a parte non servirebbe nemmeno tanto.

    Detto però meglio in generale: se il processo lanciato scrive molto su standard-output/error allora tale output deve essere letto lato Java, altrimenti il processo può bloccarsi (questioni di buffering). Quindi un thread a parte ci vorrebbe veramente.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  2. #2
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Corretto sì, lo è. Si potrebbe far notare una cosa però. Il exec() avvia il processo in modo asincrono, ovvero exec è praticamente immediato. Se non devi attendere la fine del processo per prendere il suo exit-code e non devi fornire al processo dati continui su standard-input oppure leggere i suoi standard-output/error, allora il nuovo thread a parte non servirebbe nemmeno tanto.

    Detto però meglio in generale: se il processo lanciato scrive molto su standard-output/error allora tale output deve essere letto lato Java, altrimenti il processo può bloccarsi (questioni di buffering). Quindi un thread a parte ci vorrebbe veramente.
    Ti ringrazio molto per la completezza della tua risposta perché oltre a darmi una utile conferma di quanto ho fatto, mi hai anche tolto un dubbio che avevo e non avevo proprio esposto e cioè se la lettura degli InputStream dell'oggeto Process fosse una opzione oppure un obbligo.
    Siccome il contenuto di questo stream non mi interessa più di tanto e neppure il suo exitCode, visto che se in un ciclo dovesse esserci qualche problema non conterebbe più di tanto, poiché questi cicli di generazione/invio dei files avvengono ogni 30 secondi.
    Da quello che mi hai scritto invece sembra essere molto importante che io legga di volta in volta questo InputStream del processo(anche se non mi interessa il suo contenuto), gestendo tutto in un try-catch con un finally che provvederebbe di volta in volta a garantire la chiusura dello stream stesso.
    Attualmente ho aggiunto questo thread aggiuntivo all'edt soltanto per fare in modo che si instaurasse un contesto concorrente tra l'edt ed il processo di invio dei files che può richiedere diversi secondi per concludersi.
    Ma se tu mi scrivi che già internamente l'utilizzo di Runtime.exec crea di suo un nuovo thread, allora mi pare di capire che questo nuovo thread che ho aggiunto per non influenzare l'edt sia praticamente inutile per questo scopo.
    Quindi l'unica causa plausibile che ogni tanto ha causato dei veri e propri dead-locks dell'applicativo non può che risiedere nella saturazione del buffer utilizzato dalla jvm per salvare l'output del processo.
    Mi confermi quindi che è fondamentale che io legga l'inputstream e l'errorstream del processo e provveda sempre a chiudere questi stream ad ogni ciclo di invocazione dell'eseguibile esterno in modo da liberare tutte le risorse utilizzate da questi stream del processo e scongiurare il rischio di dead-lock del'applicativo?
    Confermo che l'acquisizione dei due stream del processo che recentemente avevo pensato di escludere era già stata fatta in un altro suo thread specifico che provvedeva a leggerne il contenuto e che chiudeva gli stream alla fine.
    Inoltre il processo non richiede l'invio continuo di dati e non manda neppure uno stream lungo che richiede grossi buffer per potere essere memorizzato e letto.
    E' semplicemente un eseguibile che rimane sempre attivo e non si conclude mai.
    Per questo non sono potuto rimanere in attesa del suo exitCode e neppure fare un join sul thread che ne gestisce l'inputstream e l'errorstream per mettere in attesa il current-thread fino a quando tali stream si concludevano.
    Proprio perché non c'è alcuna uscita del processo stesso ed a Swing interessa soltanto che questo processo venga avviato e che inizi a generare periodicamente questi files ogni 30 secondi.
    Swing non deve fare altro che eseguire questo processo esterno una sola volta all'avvio e poi reinviare tali files ogni 30 secondi.
    La fase di invio dei file al server remoto è ovviamente la cosa più dispendiosa in termini di tempo ed è per questo che avevo pensato di creare un altro thread che la gestisse.
    Forse ora mi sono spiegato meglio sul sistema.
    Grazie di nuovo.
    Ultima modifica di Samaritan; 05-04-2014 a 17:55

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Samaritan Visualizza il messaggio
    se la lettura degli InputStream dell'oggeto Process fosse una opzione oppure un obbligo.
    Proprio "obbligo" no. Nel senso che se tu sai che il processo non fa assolutamente output o se di per sé può farne ma l'hai avviato con una qualche sua opzione che lo rende "quiet" (silenzioso) .... allora non è veramente necessario leggere gli stream di Process.

    Quote Originariamente inviata da Samaritan Visualizza il messaggio
    Ma se tu mi scrivi che già internamente l'utilizzo di Runtime.exec crea di suo un nuovo thread
    exec non crea alcun thread! Semplicemente la richiesta al sistema di avviare un nuovo processo è una cosa che richiede frazioni di un secondo .... non secondi o minuti.

    Quote Originariamente inviata da Samaritan Visualizza il messaggio
    Mi confermi quindi che è fondamentale che io legga l'inputstream e l'errorstream del processo e provveda sempre a chiudere questi stream ad ogni ciclo di invocazione dell'eseguibile esterno in modo da liberare tutte le risorse utilizzate da questi stream del processo e scongiurare il rischio di dead-lock del'applicativo?
    Se il processo fa "abbastanza" output su standard-output e/o standard-error, ripeto che gli stream di Process vanno letti.
    Per sapere se il processo fa dell'output, documentati se ha una documentazione o comunque provalo "a mano" da una console.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.