ConcurrentModificationException e os fail-fast iterators um outro ponto de vista

A java.util.ConcurrentModificationException costuma surpreender a muitos: como uma exception com esse nome pode aparecer mesmo em uma aplicação single threaded, que não envolve concorrência alguma no acesso dessa coleção??

Single Threaded no que se refere á programações multiplas , por exemplo um Handling database connections using SingleThreadModel , o mais curioso é porque fez observação para coleções ?

Sim, é uma concorrencia que poderiamos observar em outras situações como pertinentes a banco de dados envolvendo persistencia.

Exception in thread "pool-1-thread-1" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(Unknown Source) at java.util.HashMap$ValueIterator.next(Unknown Source) at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:555)

This is not a synchronization problem. This will occur if the underlying collection that is being iterated over is modified by anything other than the Iterator itself.

Iterator it = map.iterator(); while (it.hasNext()) { Object item = it.next(); map.remove(item); }
This will throw a ConcurrentModificationException when the it.hasNext() is called the second time.

The correct approach would be

Iterator it = map.iterator(); while (it.hasNext()) { Object item = it.next(); it.remove(item); } Assuming this iterator supports the remove() operation.

Erm… tens alguma pergunta a fazer, dúvidas sobre o uso dele, qualquer coisa para podermos iniciar uma discussão?

Tô meio perdido aqui procurando o objetivo do tópico.

Essa exceção é disparada quando você tenta remover um item de uma lista que esta sendo iterada

Mas isso é uma cópia discarada do artigo do Paulo Silveira no blog da Caelum.

http://blog.caelum.com.br/2010/08/18/concurrentmodificationexception-e-os-fail-fast-iterators/

tsc, tsc, tsc…

Que coisa feia! Sua mãe não lhe ensinou a sempre citar fontes, Duran?

[quote=garcia-jj]Mas isso é uma cópia discarada do artigo do Paulo Silveira no blog da Caelum.

http://blog.caelum.com.br/2010/08/18/concurrentmodificationexception-e-os-fail-fast-iterators/[/quote]

O Tema é o mesmo mas a colocação não, estou ampliando o que podemos discorrer sobre concurrentmodificationexecption mas quando a coleção é usada de forma a projetar execção, o texto é refletido na particularidade em especifico de iterators , todavia tenho o ponto de vista na implementação esse evento pode tomar outra referencia sobre situações de bando de dados, redes, etc…, isso programaticamente muda algo como usar java.util.concurrent.ConcurrentHashMap ao texto original achei bem singular na questão de uso sobre concorrencia.

[quote=pango]tsc, tsc, tsc…

Que coisa feia! Sua mãe não lhe ensinou a sempre citar fontes, Duran?[/quote]

Pronto agora ficou melhor esclarecido.

Alguns exemplos com Iterator

[code]import java.io.;
import java.nio.
;
import java.nio.channels.;
import java.util.Iterator;
import java.net.
;

public class NonblockingSingleFileHTTPServer {

private ByteBuffer contentBuffer;
private int port = 80;

public NonblockingSingleFileHTTPServer(
ByteBuffer data, String encoding, String MIMEType, int port)
throws UnsupportedEncodingException {

this.port = port;
String header = "HTTP/1.0 200 OK\r\n"
 + "Server: OneFile 2.0\r\n"
 + "Content-length: " + data.limit() + "\r\n"
 + "Content-type: " + MIMEType + "\r\n\r\n";
byte[] headerData = header.getBytes("ASCII");

ByteBuffer buffer = ByteBuffer.allocate(
 data.limit() + headerData.length);
buffer.put(headerData);
buffer.put(data);
buffer.flip();
this.contentBuffer = buffer;

}

public void run() throws IOException {

ServerSocketChannel serverChannel = ServerSocketChannel.open();
ServerSocket  serverSocket = serverChannel.socket();
Selector selector = Selector.open();
InetSocketAddress localPort = new InetSocketAddress(port);
serverSocket.bind(localPort);
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {

  selector.select();
  Iterator keys = selector.selectedKeys().iterator();
  while (keys.hasNext()) {
    SelectionKey key = (SelectionKey) keys.next();
    keys.remove();
    try {
      if (key.isAcceptable()) {
        ServerSocketChannel server = (ServerSocketChannel) key.channel();
        SocketChannel channel = server.accept();
        channel.configureBlocking(false);
        SelectionKey newKey = channel.register(selector, SelectionKey.OP_READ);
      }
      else if (key.isWritable()) {
        SocketChannel channel = (SocketChannel) key.channel();
        ByteBuffer buffer = (ByteBuffer) key.attachment();
        if (buffer.hasRemaining()) {
           channel.write(buffer);
        }
        else {  // we're done
           channel.close();
        }
      }
      else if (key.isReadable()) {
        // Don't bother trying to parse the HTTP header.
        // Just read something.
        SocketChannel channel = (SocketChannel) key.channel();
        ByteBuffer buffer = ByteBuffer.allocate(4096);
        channel.read(buffer);
        // switch channel to write-only mode
        key.interestOps(SelectionKey.OP_WRITE);
        key.attach(contentBuffer.duplicate());
      }
    }
    catch (IOException ex) {
      key.cancel();
      try {
        key.channel().close();
      }
      catch (IOException cex) {}
    }
  }
}

}

public static void main(String[] args) {

if (args.length == 0) {
  System.out.println(
    "Usage: java NonblockingSingleFileHTTPServer file port encoding");
  return;
}

try {
  String contentType = "text/plain";
  if (args[0].endsWith(".html") || args[0].endsWith(".htm")) {
    contentType = "text/html";
  }

  FileInputStream fin = new FileInputStream(args[0]);
  FileChannel in = fin.getChannel();
  ByteBuffer input = in.map(FileChannel.MapMode.READ_ONLY, 0, in.size());

  // set the port to listen on
  int port;
  try {
    port = Integer.parseInt(args[1]);
    if (port < 1 || port > 65535) port = 80;
  }
  catch (Exception ex) {
    port = 80;
  }

  String encoding = "ASCII";
  if (args.length > 2) encoding = args[2];

  NonblockingSingleFileHTTPServer server
   = new NonblockingSingleFileHTTPServer(
     input, encoding, contentType, port);
  server.run();

}
catch (Exception ex) {
  ex.printStackTrace();
  System.err.println(ex);
}

}

}

/**

  • Java Network Programming, Third Edition
  • By Elliotte Rusty Harold
  • Third Edition October 2004
  • ISBN: 0-596-00721-3
    */

[/code]