|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
[JAVA] uso di Future
Salve,
qualcuno sa spiegarmi l'uso di Future in java? Ho letto la doc e per quello che ho capito è ciò che fa al caso mio, ossia il "risultato" del lavoro di un Thread. Purtroppo molte cose non mi sono ancora chiare. Faccio un esempio per farmi capire meglio: mettiamo il caso che ho il thread principale dovrà scrivere su console il numero del thread che attualmente sta lanciando Codice:
System.out.println("Avvio thread " + i + "\r"); Si può realizzare questo scenario con l'uso di Future? grazie a tutti
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Jul 2002
Messaggi: 4334
|
Non ho ben capito cosa devi fare
comunque vedi qui una brevissimissima guida http://digilander.libero.it/computin...html#esecutori
__________________
|Java Base| |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
grazie per la risposta immediata...
ora do un'occhiata al link che mi hai proposto cmq ogni altro suggerimento è sempre ben accetto
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
ora posto il codice che è un buon esempio per come intendevo usare i future:
Codice:
import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class HostScanner { private InetAddress host; private ExecutorService pool; private int NUMERO_MAX_THREAD = 200; public HostScanner(String h) { try { host = InetAddress.getByName(h); } catch (UnknownHostException e) { System.err.println("Specified host couldn't be found"); } } private void scan() { pool = Executors.newFixedThreadPool(NUMERO_MAX_THREAD); try { for (int port = 0; port < 65535; port++) { System.out.print("Scanning port: " + port + "\r"); Future<Boolean> f = pool.submit(new PortScanner(host, port)); if(f.get()) { System.out.println("Porta: " + port + ": APERTA"); } } pool.shutdown(); } catch (Exception e) {} } public static void main(String[] args) { long start = System.currentTimeMillis(); new HostScanner("192.168.0.7").scan(); long end = System.currentTimeMillis(); System.out.println("Total time: " + (end - start)); } } Codice:
import java.net.InetAddress; import java.net.Socket; import java.util.concurrent.Callable; public class PortScanner implements Callable<Boolean> { private InetAddress host; private int port; public PortScanner(InetAddress h, int p) { host = h; port = p; } public Boolean call() throws Exception { Socket test; try { test = new Socket(host, port); test.setSoTimeout(100); test.close(); return new Boolean(true); } catch (Exception e) { return new Boolean(false); } } } tra l'altro è piuttosto lento...ma dipende cmq dal socket o sbaglio? c'è un modo per velocizzarlo???
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jul 2002
Messaggi: 4334
|
Con f.get() ti blocchi finché il Callable non ha terminato,
quindi è praticamente sequenziale. Prova a mettere i Future in una mappa <n.porta, Future>, che "conterrà" (devi fare f.get()) true se la porta corrispondente è aperta.
__________________
|Java Base| |
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Quote:
non ho capito allora come posso "parallelizzare" il tutto. Se metto tutto in una mappa, sempre facendo f.get(), non sto punto e a capo???
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Volendo usare un thread-pool e i Future, dovresti:
- inviare tutti i task tramite submit(). I Future ottenuti li metti da qualche parte, es. in un array. - invocare shutdown(). (non vuol dire che termina tutto di brutto, vuol dire che nuovi task non sono accettati ma quelli in esecuzione possono continuare fino alla loro terminazione) - invocare awaitTermination() per attendere la terminazione di tutti i task. A quel punto usi tutti i Future. P.S. come tipo parametrico di Future hai usato un Boolean. Io metterei un tipo specifico che contiene host/porta/stato.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
ok per il tipo di dato, ho capito come avresti fatto tu, sono solo di curioso di saperne i motivi...per imparare, tutto qui!
per il resto, la questione centrale, dovrei fare una cosa del tipo: Codice:
for (int i = 0; i < 65535; i++) { System.out.print("Scanning port: " + i + "\r"); Future<OggettoAncoraSenzaNome> f = pool.submit(new PortScanner(host, i)); < qui metto tutti i future f in un array > } pool.shutdown(); pool.awaitTermination(1000L, TimeUnit.SECONDS); ora però mi sorge un dubbio: in questo modo praticamente sto aspettando che tutti i task siano completati e a quanto ho capito awaitTermination() serve per impostare un minimo di timeout, nel caso l'attesa del completamento di tutti i task sia eccessiva. Quindi praticamente è bloccante. In questa situazione il risultato dello "scan" lo conosco solo al termine di tutti i task (insomma se la 80 è aperta o meno lo so nello stesso istante in cui conosco lo stato di tutte le porte). Giusto????
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Se non ti va bene questo tipo di approccio, allora devi usare un altro sistema, ad esempio il tipico schema produttore-consumatore.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
questo approccio va bene. Chiedo solo per cercare di capire ed imparare. ora ho la possibilità di provare il codice, poi posto e faccio sapere.
PS: riguardo all'uso dell'oggetto che contiene, come dicevi tu, host+porta+stato, mi puoi giustificare questa tua scelta? Grazie a tutti e 2 per le risposte!
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
ecco il codice che ho corretto:
Codice:
import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class HostScanner { private InetAddress host; private Future[] futures; private int NUMERO_MAX_THREAD = 200; public HostScanner(String h) { try { host = InetAddress.getByName(h); } catch (UnknownHostException e) { System.err.println("Specified host couldn't be found"); } futures = new Future[1024]; } private void scan() { ExecutorService pool = Executors.newFixedThreadPool(NUMERO_MAX_THREAD); try { for (int port = 0; port < 1024; port++) { System.out.print("Scanning port: " + (port+1) + "\r"); Future<PortScan> f = pool.submit(new PortScanner(host, port)); futures[port] = f; } pool.shutdown(); pool.awaitTermination(1000, TimeUnit.SECONDS); } catch (Exception e) {} } private String getResult() { PortScan ps = null; String s = "\n"; for (int port = 0; port < futures.length; port++) { try { ps = (PortScan) futures[port].get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } s += ps.getHost().toString() + ":" + ps.getPort() + " -> " + ps.getStatus() + "\n"; } return s; } public static void main(String[] args) { long start = System.currentTimeMillis(); HostScanner hs = new HostScanner("127.0.0.1"); hs.scan(); System.out.println(hs.getResult()); long end = System.currentTimeMillis(); System.out.println("Total time: " + (end - start)); } } Codice:
import java.net.InetAddress; public class PortScan { private InetAddress host; private int port; private String status; public static final String OPEN = "APERTA"; public static final String CLOSE = "CHIUSA"; public PortScan(InetAddress h, int p, String s) { host = h; port = p; status = s; } public InetAddress getHost() { return host; } public int getPort() { return port; } public String getStatus() { return status; } } Codice:
import java.net.InetAddress; import java.net.Socket; import java.util.concurrent.Callable; public class PortScanner implements Callable<PortScan> { private InetAddress host; private int port; public PortScanner(InetAddress h, int p) { host = h; port = p; } public PortScan call() throws Exception { Socket test; try { test = new Socket(host, port); test.close(); return new PortScan(host, port, PortScan.OPEN); } catch (Exception e) { return new PortScan(host, port, PortScan.CLOSE); } } }
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 00:55.