31. Modo de suspensión guardada: esperando que se mejore la especificación del mecanismo de activación, modo de diseño concurrente

1. escena

Versión web del navegador de archivos, a través de la cual los usuarios pueden ver los directorios y archivos en el servidor en el navegador. Este proyecto se basa en el servicio de exploración de archivos provisto por el departamento de operación y mantenimiento, y este servicio de exploración de archivos solo admite el acceso a la cola de mensajes (MQ). La cola de mensajes se usa ampliamente en grandes compañías de Internet, principalmente para el pico de tráfico y el desacoplamiento del sistema. En este modo de acceso, las dos operaciones de envío de mensajes y consumo de resultados son asíncronas.
Inserte la descripción de la imagen aquí

class Message {
	String id;
	String content;
}
// 该方法可以发送消息
	void send(Message msg) {
		// 省略相关代码
	}

	// MQ消息返回后会调用该方法
	// 该方法的执行线程不同于
	// 发送消息的线程
	void onMessage(Message msg) {
		// 省略相关代码
	}

	// 处理浏览器发来的请求
	Respond handleWebReq(){
	  //创建一消息
	  Message msg1 = new Message("1","{...}");
	  //发送消息
	  send(msg1);
	  //如何等待MQ返回的消息呢?
	  String result = ...;
	}

Pregunta: El hilo que envía mensajes a MQ es el hilo T1 que procesa la solicitud web, pero el hilo que consume el resultado de MQ no es el hilo T1. ¿Cómo espera el hilo T1 el resultado de la devolución de MQ?

2. Suspensión protegida 模式

Suspensión protegida, suspendida protectora.
Inserte la descripción de la imagen aquí

class GuardedObject<T> {
	// 受保护的对象
	T obj;
	final Lock lock = new ReentrantLock();
	final Condition done = lock.newCondition();
	final int timeout = 1;

	// 获取受保护对象
	T get(Predicate<T> p) {
		lock.lock();
		try {
			// MESA管程推荐写法
			while (!p.test(obj)) {
				done.await(timeout, TimeUnit.SECONDS);
			}
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		} finally {
			lock.unlock();
		}
		// 返回非空的受保护对象
		return obj;
	}

	// 事件通知方法
	void onChanged(T obj) {
		lock.lock();
		try {
			this.obj = obj;
			done.signalAll();
		} finally {
			lock.unlock();
		}
	}
}

3. Expanda el modo de suspensión protegida

class GuardedObject<T> {
	// 受保护的对象
	T obj;
	final Lock lock = new ReentrantLock();
	final Condition done = lock.newCondition();
	final int timeout = 2;
	// 保存所有GuardedObject
	final static Map<Object, GuardedObject> gos = new ConcurrentHashMap<>();

	// 静态方法创建GuardedObject
	static <K> GuardedObject create(K key) {
		GuardedObject go = new GuardedObject();
		gos.put(key, go);
		return go;
	}

	static <K, T> void fireEvent(K key, T obj) {
		GuardedObject go = gos.remove(key);
		if (go != null) {
			go.onChanged(obj);
		}
	}

	// 获取受保护对象
	T get(Predicate<T> p) {
		lock.lock();
		try {
			// MESA管程推荐写法
			while (!p.test(obj)) {
				done.await(timeout, TimeUnit.SECONDS);
			}
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		} finally {
			lock.unlock();
		}
		// 返回非空的受保护对象
		return obj;
	}

	// 事件通知方法
	void onChanged(T obj) {
		lock.lock();
		try {
			this.obj = obj;
			done.signalAll();
		} finally {
			lock.unlock();
		}
	}
}

Usa el objeto guardado ampliado para resolver el problema de los compañeros de clase de Xiaohui.

// 处理浏览器发来的请求
	Respond handleWebReq() {
		int id = 序号生成器.get();
		// 创建一消息
		Message msg1 = new Message(id, "{...}");
		// 创建GuardedObject实例
		GuardedObject<Message> go = GuardedObject.create(id);
		// 发送消息
		send(msg1);
		// 等待MQ消息
		Message r = go.get(t -> t != null);
	}

	void onMessage(Message msg) {
		// 唤醒等待的线程
		GuardedObject.fireEvent(msg.id, msg);
	}

// TODO no entiende

97 artículos originales publicados · elogiados 3 · 10,000+ vistas

Supongo que te gusta

Origin blog.csdn.net/qq_39530821/article/details/102789330
Recomendado
Clasificación