2013-10-15 16 views
6

In Java 1.4 +, Ci sono 3 modi per interrompere un flusso che viene bloccato sul socket I/O:rete interrompibile di I/O in Java

  1. Se la presa è stata creata usando un normale java.net.Socket(InetAddress, int) costruttore, Posso close it da un thread separato. Di conseguenza, un SocketException viene generato nel thread bloccato.
  2. Se il socket è stato creato utilizzando SocketChannel.open(...). socket() (I/O non bloccante) - di nuovo, è possibile chiuderlo da un thread separato, ma ora un'altra eccezione (uno AsynchronousCloseException) viene generata nel thread bloccato.
  3. Inoltre, nel caso si utilizzi l'I/O non bloccante, è possibile interrompere un thread bloccato, con un lancio di ClosedByInterruptException. L'interruzione di un thread bloccato quando si utilizza I/O Java vecchio stile non ha alcun effetto sul thread.

Domande:

  1. sta chiudendo una presa da un thread separato thread-safe quando si utilizza vecchio stile I/O? In caso contrario, quali sono le alternative?
  2. È in corso la chiusura di una presa/canale da una filettatura separata thread-safe quando si utilizza NIO?
  3. C'è qualche differenza nel comportamento di Socket.close() quando si utilizza NIO anziché IO ​​normale?
  4. Esistono vantaggi dell'utilizzo di NIO per il networking diverso da una possibilità di terminare un'operazione di I/O bloccata semplicemente interrompendo un thread (in modo che non sia più necessario mantenere un riferimento al socket)?

risposta

3

Quando si utilizza un I/O vecchio stile, si sta chiudendo un socket da un thread thread separato? In caso contrario, quali sono le alternative?

sì.

Un'alternativa è utilizzare il blocco NIO (che è il comportamento predefinito di un SocketChannel BTW). Preferisco questo per un numero limitato di connessioni poiché ha l'efficienza di NIO, ma un po 'della semplicità di I/O semplice.

La chiusura di un socket/canale da un thread separato thread-safe quando si utilizza NIO invece?

Sia per il blocco NIO, sia per il blocco NIO, sono thread-safe.

C'è qualche differenza nel comportamento Socket.close() quando si utilizza NIO anziché IO ​​normale?

Se è necessario conoscere i dettagli, suggerisco di leggere il codice, ma in pratica sono gli stessi.

Esistono vantaggi dell'utilizzo di NIO per il collegamento in rete oltre alla possibilità di interrompere un'operazione di I/O bloccata semplicemente interrompendo un thread (in modo che non sia più necessario mantenere un riferimento al socket)?

Il modo in cui si chiude una connessione è l'ultimo dei problemi. Quindi sì, ci sono molte ragioni per considerare NIO su un semplice IO.

Pro per NIO

  • veloce e peso più leggero quando si usa la memoria diretta
  • Ulteriori scalabili in decine di migliaia di utenti.
  • Supporta un'attiva attesa efficiente.

Contro

  • Plain IO è più semplice da codice.
  • Molte API supportano solo l'I/O semplice per questo motivo.
0

1) Poiché l'errore di chiamata del sistema operativo sottostante che raschia l'eccezione proviene da uno stack TCP che è a conoscenza del multithread, non dovrebbero esserci problemi.

2) Non sono sicuro, non l'ho provato, ma sarei sorpreso se ci fosse qualche problema.

3) Ci possono essere alcune differenze di prestazioni. Una chiamata OS close() richiede un handshake a 4 vie con il peer TCP - non è sicuro quale sistema operativo supporti quello in modo non bloccante, (lo stesso con connect).

4) Thread..or presa. Devi mantenere un riferimento a qualcosa. Dato che stai chiudendo il socket, sembra ragionevole mantenere un riferimento ad esso :)