Ocho, java multithreading bases de conocimientos y contrato Resumen

I. Antecedentes

1. blog anterior que introdujo los conceptos básicos de multithreading y sus ejemplos prácticos para nosotros hoy y digamos contrato java siguientes conocimientos, los artículos anteriores se puede referir a mi blog anterior, pero si no dice incorrecto, por favor, corríjanme el mensaje de bienvenida.

2. El propósito de escribir este blog es para mejorar sus conocimientos bajo la red, no es el uso que el proyecto actual, sino también la esperanza de ayudar a todos a entender mejor el conocimiento, por lo general bajo acumulan, se forma sutil fuerte red de conocimiento, y preámbulos, vamos a trabajar juntos para aprender bajo la barra.

En segundo lugar, los contenedores síncronas (bajo contrato)

ArrayList y la diferencia 1.Vector

Lista 1.1.ArrayList es la clase más común de aplicación, el interior se logra a través de una serie de elementos que permite el acceso rápido al azar. La desventaja es que la matriz no puede tener un espacio entre cada elemento cuando el tamaño de la matriz no satisface la necesidad de aumentar la capacidad de almacenamiento, es necesario hablar se ha copiado en la nueva matriz de espacio de almacenamiento de datos. Al insertar o eliminar un elemento de la posición intermedia de ArrayList, se requiere la matriz para copiar, mover, el costo es relativamente alto. Por lo tanto, es adecuado para la búsqueda y de recorrido aleatorio, no es adecuado para la inserción y eliminación.

1.2.Vector y ArrayList, al igual que a través de la matriz para lograr, excepto que admite la sincronización hilo, que sólo un hilo a la vez puede escribir Vector, evitar multi-threading al escribir la inconsistencia causada, pero requiere alta sincronización el costo, por lo tanto, tener acceso a ella de acceso más lento ArrayList

Nota:  el vector thread- seguro, hilo ArrayList no es seguro

Fuente Clase vectorial (el método Add () del código fuente de la clase)

ArrayList tipo de fuente (fuente método add ())

2.HashTable 与 HashMap

2.1.HashMap no seguro para subprocesos, el HashMap es sub-interfaz es una interfaz mapa de interfaz, el objeto se asigna a un valor de clave, en el que las claves y los valores son objetos, y no puede contener duplicados de las llaves, pero puede contener un valor duplicado. HashMap permite clave nula y sin valor nulo, y no está permitido tabla hash.

2.2.HashTable Collection es un hilo de seguridad.

2.3.HashMap tabla hash es la realización de peso ligero (no seguro para subprocesos aplicación), han completado la interfaz del mapa, la diferencia principal es que HashMap permite nula clave (key) (nulo), debido a la no-thread-safe, la eficiencia puede ser mayor que tabla hash.
HashMap permite nulo como una entrada de clave o el valor, y no se permite Hashtable.
HashMap Hashtable contiene métodos eliminan, sustituyen containsKey containsvalue.

Nota: thread- HashTable seguro, HashMap thread- insegura .

3.ConcurrentHashMap

3.1 Debido a que el HashTable caja fuerte cerrada, pero sólo se puede hacer una operación de bloqueo de rosca, por lo que el impacto de la eficiencia, esta vez inventó ConcurrentHashMap, el principio como se muestra a continuación:

Hay dos interfaces en 3.2.ConcurrentMap realización importante:
ConcurrentHashMap
(. Apoyar la función de clasificación concurrente para compensar las ConcurrentHas p-HMA) ConcurrentSkipListMap
ConcurrentHashMap segmento uso interno (Segmento) para representar estas secciones diferentes, cada sección es en realidad una
pequeña HashTable, se tiene su propio candado. Mientras varias modificaciones se producen en diferentes secciones, y pueden
envían realizado. El conjunto se divide en un 16 segmento (Segment. Es decir, hasta 16 hilos concurrentes operación de modificación.
Esta es también la granularidad de bloqueo hilo grueso escena se reduce reduciendo de ese modo la contención de bloqueo de una solución. La mayor parte del código y las variables compartidas
el uso de la palabra clave volátil para declarar el fin de obtener la primera vez modificar el contenido de la actuación es muy buena.

4.CountDownLatch

java.util.concurrent clase 4.1.CountDownLatch situada bajo el paquete, que puede implementarse usando un contador funcionalmente similar. Por ejemplo, no es una tarea A, se espera a la otra para llevar a cabo después de la finalización de cuatro tareas a realizar, a continuación, puede utilizar esta función para lograr el CountDownLatch (similar al método join ()).

4.2. Código

public class Test002 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("等待子线程执行完毕...");
        CountDownLatch countDownLatch = new CountDownLatch(2);
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("子线程," + Thread.currentThread().getName() + "开始执行...");
                countDownLatch.countDown();// 每次减去1
                System.out.println("子线程," + Thread.currentThread().getName() + "结束执行...");
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("子线程," + Thread.currentThread().getName() + "开始执行...");
                countDownLatch.countDown();
                System.out.println("子线程," + Thread.currentThread().getName() + "结束执行...");
            }
        }).start();
        countDownLatch.await();// 调用当前方法主线程阻塞  countDown结果为0, 阻塞变为运行状态
        System.out.println("两个子线程执行完毕....");
        System.out.println("继续主线程执行..");
    }
}

4.3 resultados

En tercer lugar, la cola concurrente

1. En el JDK proporciona dos aplicación cola concurrente, es un alto rendimiento ConcurrentLinkedQueue representado cola, un representante de la interfaz es BlockingQueue cola de bloqueo, no importa lo que se heredan de la cola.

2.ConcurrentLinkedQueue: es una escena adecuado para una cola altamente concurrente, por cierto, para lograr un alto rendimiento en estado de alta concurrencia libre de bloqueo, ConcurrentLinkedQueue generalmente un buen rendimiento en BlockingQueue que se basa en nodos enlazados. Cola thread-safe ilimitada . Elementos de la cola se atengan al principio FIFO. La primera cabeza se unió, al final de la última adición, la cola no permite elementos nulos.

2.1.ConcurrentLinkedQueue métodos importantes: complemento y la oferta () es un método de añadir elementos (tal vez no en ConcurrentLinkedQueue en un método de diferencia)
poll () y peek () es tomar el primer nodo de elemento, excepto que se elimina el elemento, este último no lo hará.

2.2 Código (resultados auto facie)

ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
	q.offer("小明");
	q.offer("小红");
	q.offer("小张");
	q.offer("小诺");
	q.offer("小华");
	//从头获取元素,删除该元素
	System.out.println(q.poll());
	//从头获取元素,不刪除该元素
	System.out.println(q.peek());
	//获取总长度
	System.out.println(q.size());

3.BlockingQueue: el bloqueo de cola (BlockingQueue) es una de dos colas de apoyar las operaciones adicionales. Estas dos operaciones adicionales son:

3.1. En la cola está vacía al recuperar un elemento de hilo espera para la cola para convertirse en no vacío.
Cuando la cola está llena, el hilo va a esperar cola elementos de almacenamiento disponible. 

El bloqueo de cola utilizado comúnmente en los productores y consumidores de la escena, se añade el productor a los elementos de hilo de cola, el consumidor es tomar elementos de la rosca cola. El bloqueo de almacenamiento de cola elemento contenedor es los productores, y los consumidores sólo tienen elementos de recipiente.

3.2.BlockingQueue que está bloqueando la cola de bloqueo se puede ver en la palabra, y en algunos casos bloquearon el acceso a la cola puede causar el bloqueo. Hay casos bloquearon las principales dos siguientes:

1. Cuando la cola está llena cuando se lleva en las colas

2. Cuando el tiempo de espera para una operación de cola vacía

Por lo tanto, cuando un intento de hilo tenga una cola llena de colas en funcionamiento, será bloqueado, a menos que exista otro hilo para hacer la operación cola; mismo modo, cuando un hilo intenta vaciar la operación de cola de cola , será bloqueado, a menos que exista otro hilo en la operación de cola.

3. Interfaz En Java, BlockingQueue situado en el paquete java.util.concurrent (disponible a partir de la versión Java5), mediante el bloqueo de características de la cola se ha descrito anteriormente muestra que el bloqueo de cola es thread-safe.

En el nuevo paquete concurrente, buena solución BlockingQueue a múltiples hilos, lo eficiente y seguro "transferencia" de los problemas de datos. Estos clase cola eficiente y seguro para subprocesos, una gran comodidad para nosotros construir rápidamente programas multi-hilo de alta calidad. Este artículo describe el BlockingQueue todos los miembros de la familia, incluyendo sus respectivas funciones y escenarios de uso común.

comprensión BlockingQueue

El bloqueo de cola, como su nombre lo indica, se trata de una primera cola y un papel estructura de datos de la cola sustancialmente como se muestra a continuación:

De la figura podemos ver claramente a través de una cola compartida, por lo que los datos se pueden introducir desde un extremo de la cola se emite desde el otro extremo;

Queuing, hay dos implementaciones principal :( diferente, por supuesto, también puede extenderse muchos tipos diferentes de colas, un DelayQueue es uno de ellos)

  First In First Out (FIFO): los primeros elementos también se insertan en la primera cola de la cola, las funciones de colas gusta. Hasta cierto punto, esto también refleja una imparcialidad cola.

  Última en entrar, primero en salir (LIFO): Después de insertar el primer elemento de la cola de la cola, la prioridad de la cola de los acontecimientos recientes.

      ambiente Multi-roscado, el intercambio de datos se puede conseguir fácilmente a través de la cola, tal como el "productor" clásico y el modelo de "consumidor", que puede facilitar el intercambio de datos entre los dos a través de la cola. Supongamos que tenemos un número de hilo productor, hay un número de hilo consumidor adicional. Si la necesidad hilo productor de compartir datos a los consumidores de hilo listo, utilizando el camino cola para pasar los datos, se puede resolver fácilmente los datos que comparten problemas entre ellos. Pero si los productores y consumidores en un determinado período de tiempo, la situación no concuerda con los datos de la velocidad de procesamiento del evento ocurra? Idealmente, si la tasa de datos de salida del productor es mayor que la tasa de gasto de los consumidores, y cuando los datos de producción acumulativos fuera en cierta medida, entonces el productor debe pausa para esperar que (bloqueo hilo productor), con el fin de esperar a que los consumidores enhebrar los datos acumulados se procesa, y viceversa. Sin embargo, antes de que el paquete de la versión concurrente, en un entorno multiproceso, tenemos que poseer todos los programadores para controlar estos detalles, en particular, sino también en la eficiencia y flujos seguros, y esto le dará a nuestro programa no es un pequeño grado de complejidad . Afortunadamente, esta vez, un fuerte paquete concurrente resultó, pero también nos da una poderosa BlockingQueue. (En un zonas multiproceso: la llamada de bloqueo, en algunos casos colgado hilos (es decir, bloqueado), una vez que se cumplen las condiciones, el hilo suspendido será despertado automáticamente).

4. La ilustración siguiente muestra dos BlockingQueue dos escenarios comunes de bloqueo:

4.1.ArrayBlockingQueue: Hay un bloqueo de las fronteras de la cola, su aplicación interna es una matriz. Hay un significado límite de su capacidad está limitada, tenemos que especificar el tamaño de su capacidad en el momento de su inicialización, la capacidad del tamaño especificado una vez que es inmutable. ArrayBlockingQueue es datos FIFO almacenados, objeto recién insertado es la cola, el último objeto se retira de la cabeza. Aquí está un ejemplo de un ArrayBlockingQueue inicialización y uso:

ArrayBlockingQueue<String> arrays = new ArrayBlockingQueue<String>(3);
	arrays.add("李四");
	 arrays.add("张军");
	arrays.add("张军");
	// 添加阻塞队列
	arrays.offer("张三", 1, TimeUnit.SECONDS);

configuración de tamaño de la cola 4.2.LinkedBlockingQueue bloqueo es opcional, si especificamos un tamaño cuando se inicializa, es limitada, si no se especifica, es sin fronteras. Él dice que es sin bordes, de hecho, es el uso de un tamaño predeterminado de la capacidad Integer.MAX_VALUE. Su implementación interna es una lista enlazada.

Y ArrayBlockingQueue igual, LinkedBlockingQueue también almacenar datos de manera FIFO, el objeto recién insertado es la cola, el último objeto se quita de la cabeza. El siguiente es un ejemplo de inicialización y para hacer que el LinkedBlockingQueue:

LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue(3);
linkedBlockingQueue.add("张三");
linkedBlockingQueue.add("李四");
linkedBlockingQueue.add("李四");
System.out.println(linkedBlockingQueue.size());

4.3.PriorityBlockingQueue no es una de las fronteras de la cola, su cotejo y java.util.PriorityQueue misma. Nota permite la inserción PriorityBlockingQueue de objetos nulos. Todos los objetos insertados PriorityBlockingQueue java.lang.Comparable debe implementar la interfaz, prioridad de la cola es de acuerdo con las reglas de la clase nos damos cuenta de esta interfaz para definir. Además, podemos obtener un iterador iterador de PriorityBlockingQueue, pero esto no garantiza que el iterador a lo largo de conformidad con la prioridad.

4.4. Código (uso BlockingQueue a los productores y consumidores Simular )

class ProducerThread extends Thread {
    private BlockingQueue queue;
    private volatile boolean flag = true;
    private static AtomicInteger count = new AtomicInteger();
    ProducerThread(BlockingQueue blockingQueue) {
        this.queue = blockingQueue;
    }
    @Override
    public void run() {
        System.out.println("生产者线程启动...");
        try {
            while (flag) {
                System.out.println("正在生产队列");
                String data = count.incrementAndGet() + "";
                // 添加队列
                boolean offer = queue.offer(data);
                if (offer) {
                    System.out.println("生产者添加队列" + data + "成功!");
                } else {
                    System.out.println("生产者添加队列" + data + "失败!");
                }
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            System.out.println("生产者线程停止...");
        }
    }
    public void stopThread() {
        this.flag = false;
    }
}
class ConsumerThread extends Thread {
    private BlockingQueue queue;
    private volatile boolean flag = true;

    ConsumerThread(BlockingQueue blockingQueue) {
        this.queue = blockingQueue;
    }
    @Override
    public void run() {
        System.out.println("消费者线程启动....");
        try {
            while (flag) {
                // 获取完毕,队列会删除掉
                String data = (String) queue.poll(2, TimeUnit.SECONDS);
                if (data != null) {
                    System.out.println("消费者获取 data:" + data + "成功...");
                } else {
                    System.out.println("消费者获取 data:" + data + "失敗..");
                    this.flag = false;
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            System.out.println("消费停止....");
        }
    }
}
public class Test006 {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> queue = new LinkedBlockingQueue<String>(10);
        ProducerThread p1 = new ProducerThread(queue);
        // ProducerThread p2 = new ProducerThread(queue);
        ConsumerThread c1 = new ConsumerThread(queue);
        p1.start();
        // p2.start();
        c1.start();
        // 执行10s
        Thread.sleep(10 * 1000);
        p1.stopThread();
        // p2.stopThread();
    }
}

4.4 resultados

生产者线程启动...
正在生产队列
消费者线程启动....
生产者添加队列1成功!
消费者获取 data:1成功...
正在生产队列
生产者添加队列2成功!
消费者获取 data:2成功...
正在生产队列
生产者添加队列3成功!
消费者获取 data:3成功...
正在生产队列
生产者添加队列4成功!
消费者获取 data:4成功...
正在生产队列
生产者添加队列5成功!
消费者获取 data:5成功...
正在生产队列
生产者添加队列6成功!
消费者获取 data:6成功...
正在生产队列
生产者添加队列7成功!
消费者获取 data:7成功...
正在生产队列
生产者添加队列8成功!
消费者获取 data:8成功...
正在生产队列
生产者添加队列9成功!
消费者获取 data:9成功...
正在生产队列
生产者添加队列10成功!
消费者获取 data:10成功...
生产者线程停止...
消费者获取 data:null失敗..
消费停止....

En cuarto lugar, el fin de la

¡¡¡Siempre mantén la fe!!! 

Publicados 122 artículos originales · ganado elogios 64 · Vistas a 50000 +

Supongo que te gusta

Origin blog.csdn.net/chenmingxu438521/article/details/103833647
Recomendado
Clasificación