Pergunta

Eu não tenho certeza se essa é a maneira correta para sincronizar o meu ArrayList.

Eu tenho um ArrayList in_queue que é passado a partir da função registerInQueue.

ArrayList<Record> in_queue = null;

public void registerInQueue(ArrayList in_queue)
{
    this.in_queue = in_queue;
}

Agora eu estou tentando sincronizá-lo. É este sychronizing meu objeto in_queue corretamente?

List<Record> in_queue_list = Collections.synchronizedList(in_queue);

synchronized (in_queue_list) {
    while (in_queue_list.size() > 0) {
        in_queue_list.remove(0);
    }
}
Foi útil?

Solução

Você está sincronizando duas vezes, que é inútil e possivelmente retarda o código: mudanças durante a iteração sobre a necessidade lista um synchronnization ao longo de toda a operação, o que você está fazendo com synchronized (in_queue_list) Usando Collections.synchronizedList() é supérfluo nesse caso (que cria um wrapper que sincroniza operações individuais).

No entanto, desde que você está esvaziando a lista completamente, a remoção iterado do primeiro elemento é a pior maneira possível fazê-lo, sice para cada elemento de todos os elementos seguintes tem que ser copiado, tornando esta uma O (n ^ 2) operação -. terrivelmente lenta para listas maiores

Em vez disso, simplesmente chamar clear() -. Sem iteração necessário

Editar: Se você precisar a sincronização em um único método de Collections.synchronizedList() mais tarde, então este é o caminho correto:

List<Record> in_queue_list = Collections.synchronizedList(in_queue);
in_queue_list.clear(); // synchronized implicitly, 

Mas em muitos casos, a sincronização em um único método é insuficiente (por exemplo para todos iteração, ou quando você recebe um valor, fazer cálculos com base nele, e substituí-lo com o resultado). Nesse caso, você tem que usar a sincronização manual de qualquer maneira, então Collections.synchronizedList() é apenas inútil sobrecarga adicional.

Outras dicas

Olhando para o seu exemplo, eu acho que ArrayBlockingQueue (ou seus irmãos) podem ser de uso. Eles cuidam da sincronização para você, então tópicos pode escrever para a fila ou espiada / tomar sem trabalho sincronização adicional de sua parte.

Isso é correto, e documentado:

http : //java.sun.com/javase/6/docs/api/java/util/Collections.html#synchronizedList (java.util.List)

No entanto, para limpar a lista, basta ligar para List.clear () .

Sim, é o caminho correto, mas o bloco sincronizado é necessário se você quer todas as remoções em conjunto para ser seguro - a menos que a fila está vazia há remoções permitidos. Meu palpite é que você só quer fila de seguro e operações dequeue, para que possa remover o bloco sincronizado.

No entanto, há filas simultâneos muito avançadas em Java, como ConcurrentLinkedQueue

Vamos dar uma lista normal (implementada pela classe ArrayList) e torná-lo sincronizado. Isto é mostrado na classe SynchronizedListExample. Passamos o método Collections.synchronizedList um novo ArrayList de strings. O método retorna uma lista sincronizada de Strings. // Aqui é a classe SynchronizedArrayList

package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
/**
* 
* @author manoj.kumar
* @email kumarmanoj.mtech@gmail.com
* 
*/
public class SynchronizedArrayList {
    static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());
    public static void main(String[] args) {    
        List<String> synchronizedList = Collections.synchronizedList(new ArrayList<String>());
        synchronizedList.add("Aditya");
        synchronizedList.add("Siddharth");
        synchronizedList.add("Manoj");
        // when iterating over a synchronized list, we need to synchronize access to the synchronized list
        synchronized (synchronizedList) {
            Iterator<String> iterator = synchronizedList.iterator();
            while (iterator.hasNext()) {
                log.info("Synchronized Array List Items: " + iterator.next());
            }
        }    
    }
}

Observe que quando a iteração sobre a lista, este acesso ainda é feito usando um bloco sincronizado que os bloqueios no objeto synchronizedList. Em geral, a iteração sobre uma coleção sincronizado deve ser feito em um bloco sincronizado

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top