Crear una lista concurrente en Java
La concurrencia es el proceso para ejecutar programas o funciones en una ejecución paralela. Cuando varios subprocesos funcionan con el mismo método, se reduce el tiempo y aumenta el rendimiento.
Java proporciona la clase CopyOnWriteArrayList
que permite una forma eficiente de operaciones de List
, y las funciones funcionan de manera segura para subprocesos. Significa que cuando dos o más subprocesos intentan manipular la lista, entonces la clase dada permite operaciones de lectura-escritura
de una manera segura para subprocesos. Internamente, al modificar métodos de la interfaz de lista como las funciones add
o remove
, el contenido de CopyOnWriteArrayList
se copia en la nueva copia interna. Esta característica permite que sea seguro para subprocesos y permite el procesamiento en paralelo.
La clase CopyOnWriteArrayList
está presente en el paquete java.util.concurrent
. A continuación se muestra un ejemplo de bloque de código que demuestra las operaciones en la clase dada.
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);
}
}
}
Clase de controlador en Java
En el programa anterior, se definen tres clases. El primero con el método main
es la clase de controlador, y otros están ahí para funcionar. En la clase ConcurrentListOperations
, la lista temporal se inicializa con tres enteros inicialmente. El temp_list
formado se pasa al constructor CopyOnWriteArrayList
, que es otro tipo de clase ArrayList
.
La clase inicializa el array con los valores definidos anteriormente. Ahora, la instancia de copyOnWriteArrayList
se pasa a las clases de hilo creadas previamente. Esta clase solo hará que la lista sea segura para subprocesos; por lo tanto, permite operaciones paralelas en la instancia de la lista.
Clase de hilo en Java
Las dos clases de subprocesos son ReadThread
y WriteThread
. El trabajo real de la clase es leer y escribir la misma lista simultáneamente. La clase WriteThread
extiende la clase Thread
, que es una forma de declarar los hilos. Tiene un constructor público que asigna la instancia de lista recibida a la variable local e inicializa el nombre del hilo.
La lógica empresarial real de los subprocesos está presente en su método run
. Para iniciar un hilo, se llama al método start
a través de la instancia de la clase del hilo que se acaba de crear.
Utilice el método run
en Java
En el método run
de la clase WriteThread
, se inicializa un contador en la condición de bucle para rastrear las iteraciones de la clase write
en el método run
. el bucle do-while
se utiliza para llevar un registro de las ejecuciones de iteraciones.
Dentro del bloque condicional, se llama al método sleep
de la clase Thread
para hacer que el thread duerma durante el tiempo definido. La función hace que el paralelo, ejecutando el hilo, se duerma durante una cantidad definida de milisegundos. Lanza IllegalArgumentException
si los milisegundos pasados son negativos y InterruptedException
si se interrumpe algún hilo.
El método add
se usa para agregar elementos en la lista por subprocesos concurrentes. Lanza UnsupportedOperationException
si la operación no está permitida por la instancia de la lista. Por otro lado, arroja ClassCastException
si la clase del elemento especificado no es del mismo tipo de la lista. Lanza NullPointerException
si el valor especificado es nulo y IllegalArgumentException
si alguna propiedad de este elemento impide que el elemento se agregue.
De manera similar, en el método run
de la clase ReadThread
, se define un constructor; inicializa el nombre y la lista. El método run
tiene la lógica de read
real. La clase StringBuilder
se utiliza para realizar manipulaciones en la salida. El método append
agrega la salida que se encuentra en la clase de hilo de escritura con la existente.
Por lo tanto, las operaciones de lectura
y escritura
ocurren simultáneamente y se imprimen en la consola en el formato anterior. El hilo de escritura duerme durante unos 5000 milisegundos, y la salida del escritor se mostrará menos veces en comparación con el hilo de lectura
. El ...
significa que los subprocesos se ejecutan sin cesar e imprimen la misma salida porque no se ha realizado ninguna operación de escritura
. Una vez que el proceso de escritura
es un éxito, el hilo de lectura
ahora imprime el nuevo valor agregado.
Producción :
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