java notas de programación concurrente siete

modo síncrono de protección de pausa

1. Definiciones

Esa suspensión vigilado, con una espera de hilo para otro hilo de resultados de la ejecución

puntos

  • Hay una necesidad de ofrecer resultados de un hilo a otro, de modo que se asocian con una GuardedObject
  • Si alguna vez ha resultado de un hilo a otro hilo puede utilizar la cola de mensajes (véase el productor / consumidor)
  • JDK, la realización de la unión, las implementaciones futuras, se utiliza este modo de
  • Debido a que esperar a los resultados de la otra, y por lo tanto clasificarse en modo síncrono

Aquí Insertar imagen Descripción

2. Implementar

class GuardedObject {
    private Object response;
    private final Object lock = new Object();
    public Object get() {
        synchronized (lock) {
// 条件不满足则等待
            while (response == null) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return response;
        }
    }
    public void complete(Object response) {
        synchronized (lock) {
// 条件满足,通知等待线程
            this.response = response;
            lock.notifyAll();
        }
    }
}
  • Aplicación de
    un hilo espera a los resultados de otro hilo
    public static void main(String[] args) {
        GuardedObject guardedObject = new GuardedObject();
        new Thread(() -> {
            try {
			// 子线程执行下载
                List<String> response = download();
                log.debug("download complete...");
                guardedObject.complete(response);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
        log.debug("waiting...");
        // 主线程阻塞等待
        Object response = guardedObject.get();
        log.debug("get response: [{}] lines", ((List<String>) response).size());
    }

3. Con una versión de tiempo de espera GuardedObject

class GuardedObjectV2 {
    private Object response;
    private final Object lock = new Object();
    public Object get(long millis) {
        synchronized (lock) {
            // 1) 记录最初时间
            long begin = System.currentTimeMillis();
            // 2) 已经经历的时间
            long timePassed = 0;
            while (response == null) {
             // 4) 假设 millis 是 1000,结果在 400 时唤醒了,那么还有 600 要等
                long waitTime = millis - timePassed;
                log.debug("waitTime: {}", waitTime);
                if (waitTime <= 0) {
                    log.debug("break...");
                    break;
                }
                try {
                    lock.wait(waitTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 3) 如果提前被唤醒,这时已经经历的时间假设为 400
                timePassed = System.currentTimeMillis() - begin;
                log.debug("timePassed: {}, object is null {}",
                        timePassed, response == null);
            }
            return response;
        }
    }
    public void complete(Object response) {
        synchronized (lock) {
            // 条件满足,通知等待线程
            this.response = response;
            log.debug("notify...");
            lock.notifyAll();
        }
    }
}

Prueba, sin tiempo de espera

    public static void main(String[] args) {
        GuardedObjectV2 v2 = new GuardedObjectV2();
        new Thread(() -> {
            sleep(1);
            v2.complete(null);
            sleep(1);
            v2.complete(Arrays.asList("a", "b", "c"));
        }).start();
        Object response = v2.get(2500);
        if (response != null) {
            log.debug("get response: [{}] lines", ((List<String>) response).size());
        } else {
            log.debug("can't get response");
        }
    }

exportación

08:49:39.917 [main] c.GuardedObjectV2 - waitTime: 2500
08:49:40.917 [Thread-0] c.GuardedObjectV2 - notify...
08:49:40.917 [main] c.GuardedObjectV2 - timePassed: 1003, object is null true
08:49:40.917 [main] c.GuardedObjectV2 - waitTime: 1497
08:49:41.918 [Thread-0] c.GuardedObjectV2 - notify...
08:49:41.918 [main] c.GuardedObjectV2 - timePassed: 2004, object is null false
08:49:41.918 [main] c.TestGuardedObjectV2 - get response: [3] lines

Principio unirse

La persona que llama está sondeando para comprobar el estado de la rosca vivos

t1.join();Es equivalente al siguiente código

synchronized (t1) {
 // 调用者线程进入 t1 的 waitSet 等待, 直到 t1 运行结束
 while (t1.isAlive()) {
 t1.wait(0);
 }
}

4. Multitarea versión GuardedObject

capa de la FIG Futuros como buzón de edificios residenciales (buzon cada habitación tiene un número), el T0 izquierda, T2, T4 población como la espera de un mensaje, y el derecho
lado es t1, t3, t5 cartero como
si es necesario en múltiples uso entre las clases GuardedObject objeto pasado como un parámetro no es muy conveniente, por lo tanto diseñado para una clase media desacoplado,
de modo que no sólo las personas en espera de desacoplamiento [resultados] y [resultados] productores, pueden también soportar múltiples tareas de forma simultánea la gestión de
Aquí Insertar imagen Descripción
la nueva ID para identificar vigilado objeto, que GuardedObject () una clase más Identificación.

Desacoplamiento clase intermedia


class Mailboxes {
    private static Map<Integer, GuardedObject> boxes = new Hashtable<>();
    private static int id = 1;
    // 产生唯一 id
    private static synchronized int generateId() {
        return id++;
    }
    public static GuardedObject getGuardedObject(int id) {
        return boxes.remove(id);
    }
    public static GuardedObject createGuardedObject() {
        GuardedObject go = new GuardedObject(generateId());
        boxes.put(go.getId(), go);
        return go;
    }
    public static Set<Integer> getIds() {
        return boxes.keySet();
    }
}

Publicado 93 artículos originales · ganado elogios 31 · Vistas a 30000 +

Supongo que te gusta

Origin blog.csdn.net/weixin_43866567/article/details/104975596
Recomendado
Clasificación