Criar uma Lista Concorrente em Java
Simultaneidade é o processo de execução de programas ou funções paralelamente. Quando vários threads trabalham no mesmo método, isso permite uma redução do tempo e um aumento da taxa de transferência.
Java fornece a classe CopyOnWriteArrayList
que permite uma maneira eficiente de operações List
, e as funções funcionam de maneira thread-safe. Isso significa que quando duas ou mais threads tentam manipular a lista, a classe dada permite operações leitura-gravação
de uma maneira segura para threads. Internamente, ao modificar métodos da interface de lista, como as funções adicionar
ou remove
, o conteúdo de CopyOnWriteArrayList
é copiado para a nova cópia interna. Este recurso permite que ele seja seguro para thread e permite o processamento paralelo.
A classe CopyOnWriteArrayList
está presente no pacote java.util.concurrent
. Abaixo está um exemplo de bloco de código que demonstra as operações na classe fornecida.
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ConcurrentListOperations {
public static void main(String[] args) {
List<Integer> temp_list = Arrays.asList(1, 2, 3);
List<Integer> list = new CopyOnWriteArrayList<>(temp_list);
new WriteThread("Writer", list).start();
new ReadThread("Reader", list).start();
}
}
class WriteThread extends Thread {
private final List<Integer> list;
public WriteThread(String name, List<Integer> list) {
this.list = list;
super.setName(name);
}
public void run() {
int count = 4;
int counter = 0;
do {
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
list.add(count++);
System.out.println(super.getName() + " done");
counter++;
} while (counter != 5);
}
}
class ReadThread extends Thread {
private final List<Integer> list;
public ReadThread(String name, List<Integer> list) {
this.list = list;
super.setName(name);
}
public void run() {
while (true) {
StringBuilder output = new StringBuilder("\n" + super.getName() + ":");
for (Integer nextVal : list) {
output.append(" ").append(nextVal);
}
System.out.println(output);
}
}
}
Classe de driver em Java
No programa acima, três classes são definidas. A primeira com o método main
é a classe do driver, e outras estão lá para funcionar. Na classe ConcurrentListOperations
, a lista temporária é inicializada com três inteiros inicialmente. A temp_list
formada é passada para o construtor CopyOnWriteArrayList
, que é outro tipo de classe ArrayList
.
A classe inicializa a matriz com os valores definidos acima. Agora, a instância de copyOnWriteArrayList
é passada para as classes de thread criadas anteriormente. Esta classe só tornará a lista thread-safe; portanto, permitindo operações paralelas na instância da lista.
Classe Thread em Java
As duas classes de thread são ReadThread
e WriteThread
. O trabalho real da classe é ler e escrever a mesma lista simultaneamente. A classe WriteThread
estende a classe Thread
, que é uma forma de declarar os threads. Ele tem um construtor público que atribui a instância da lista recebida à variável local e inicializa o nome do thread.
A lógica de negócios real para threads está presente em seu método run
. Para iniciar um encadeamento, o método start
é chamado sobre a instância da classe de encadeamento recém-criada.
Use o método run
em Java
No método run
da classe WriteThread
, um contador é inicializado na condição de loop para rastrear as iterações da classe write
no método run
. O loop do-while
é usado para controlar a contagem das execuções de iteração.
Dentro do bloco condicional, o método sleep
da classe Thread
é chamado para fazer o thread dormir pelo tempo definido. A função faz com que o paralelo, executando o segmento para dormir por uma quantidade definida de milissegundos. Ele lança IllegalArgumentException
se os milissegundos passados forem negativos e InterruptedException
se algum encadeamento for interrompido.
O método add
é usado para adicionar elementos na lista por threads simultâneos. Ele lança UnsupportedOperationException
se a operação não for permitida pela instância da lista. Por outro lado, lança ClassCastException
se a classe do elemento especificado não for do mesmo tipo da lista. Ele lança NullPointerException
se o valor especificado for nulo e IllegalArgumentException
se alguma propriedade desse elemento impedir a adição do elemento.
Da mesma forma, no método run
da classe ReadThread
, um construtor é definido; ele inicializa o nome e a lista. O método run
tem a lógica real read
. A classe StringBuilder
é usada para fazer manipulações na saída. O método append
acrescenta a saída encontrada na classe de thread de gravação com a existente.
Conseqüentemente, as operações ler
e escrever
acontecem simultaneamente e são impressas no console no formato acima. O encadeamento de gravação dorme por cerca de 5.000 milissegundos e a saída do gravador será exibida menos vezes em comparação com o encadeamento lido
. O ...
significa que os encadeamentos estão em execução infinita e imprimindo a mesma saída porque nenhuma operação de gravação
foi feita. Assim que o processo escrever
for um sucesso, o encadeamento ler
agora imprime o valor adicionado recentemente.
Produção:
Reader: 1 2 3
..
Writer done
Reader: 1 2 3 4
...
Writer done
Reader: 1 2 3 4 5
Rashmi is a professional Software Developer with hands on over varied tech stack. She has been working on Java, Springboot, Microservices, Typescript, MySQL, Graphql and more. She loves to spread knowledge via her writings. She is keen taking up new things and adopt in her career.
LinkedIn