|
|||||||
|
|
|
![]() |
|
|
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: 08:02.











|








