并发编程:并行反应式流:编程流(Flow.Subscriber)

39 篇文章 0 订阅
13 篇文章 0 订阅

目录

主要内容

一、主程序

二、元素类

三、订阅者1

四、订阅者2

五、订阅者3

六、执行结果


主要内容

  • Flow.Publisher:发布者(提供一个方法来接收Subscriber)
  • Flow.Subscriber:订阅者(提供4个方法,分别用于:订阅完毕时,出现异常时,新元素被请求时,发布者注册订阅者时。)
  • Flow.Subscription:订阅(用于订阅者向发布者请求新元素)

一、主程序

package xyz.jangle.thread.test.n6_x.subscriber;

import java.util.concurrent.SubmissionPublisher;
import java.util.concurrent.TimeUnit;

/**
 * 6.10、编程流(发布与订阅)
 * Flow.Publisher:发布者(提供一个方法来接收Subscriber)
 * Flow.Subscriber:订阅者(提供4个方法,分别用于:订阅完毕时,出现异常时,新元素被请求时,发布者注册订阅者时。)
 * Flow.Subscription:订阅(用于订阅者向发布者请求新元素)
 * 
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年9月9日 下午4:18:41
 * 
 */
public class M {

	public static void main(String[] args) {

		var consumer1 = new Consumer1();
		var consumer3 = new Consumer3();
		SubmissionPublisher<Item> publisher = new SubmissionPublisher<Item>();
		// 发布者添加订阅者(进行订阅操作)
		publisher.subscribe(consumer1);
		publisher.subscribe(new Consumer2());
		publisher.subscribe(consumer3);
		for (int i = 0; i < 10; i++) {
			// 发布者添加主题
			var item = new Item();
			item.setTitle("title " + i);
			item.setContent("这个是Item的内容" + i);
			publisher.submit(item);
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		// 订阅者3手动请求
		consumer3.request(3);
		// 再次发布主题元素
		publisher.submit(new Item("last title","last context"));
		publisher.close();
	}

}

二、元素类

package xyz.jangle.thread.test.n6_x.subscriber;

/**
 * 元素类(含标题和内容)
 * 
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年9月9日 下午4:20:05
 * 
 */
public class Item {

	private String title, content;

	public Item() {
		super();
	}

	public Item(String title, String content) {
		super();
		this.title = title;
		this.content = content;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

}

三、订阅者1

package xyz.jangle.thread.test.n6_x.subscriber;

import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.Flow.Subscription;

/**
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年9月9日 下午4:19:44
 * 
 */
public class Consumer1 implements Subscriber<Item> {

	@Override
	public void onSubscribe(Subscription subscription) {
		// 发布者在调用subscribe()方法后,执行该方法
		System.out.println(Thread.currentThread().getName() + ":Consumer 1: 收到订阅(subscription)无Item请求");
	}

	@Override
	public void onNext(Item item) {
		// 发布者有新元素被请求时,该方法被调用。
		System.out.println(Thread.currentThread().getName() + ":Consumer 1:新增Item " + item.getTitle() + ",Content:"
				+ item.getContent());
	}

	@Override
	public void onError(Throwable throwable) {
		// 当出现错误必须通知订阅者时,该方法被调用
		System.out.println(Thread.currentThread().getName()+":Consumer 1:出现异常");
		throwable.printStackTrace();
	}

	@Override
	public void onComplete() {
		// 发布者在完成自己的任务之后,调用订阅者的onComplete()方法,也就是该方法。
		System.out.println(Thread.currentThread().getName()+":Consumer 1:完成执行");
	}

}

四、订阅者2

在onNext方法中进行了迭代请求

package xyz.jangle.thread.test.n6_x.subscriber;

import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.Flow.Subscription;

/**
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年9月9日 下午4:43:31
 * 
 */
public class Consumer2 implements Subscriber<Item> {

	private Subscription subscription;

	@Override
	public void onSubscribe(Subscription subscription) {
		// 发布者在调用subscribe()方法后,执行该方法
		System.out.println(Thread.currentThread().getName() + ":Consumer 2: 收到订阅(subscription),请求一个Item");
		this.subscription = subscription;
		this.subscription.request(1);
	}

	@Override
	public void onNext(Item item) {
		// 发布者有新元素被请求时,该方法被调用。
		System.out.println(
				Thread.currentThread().getName() + ":Consumer 2:onNext方法:" + item.getTitle() + "," + item.getContent()+"...并请求下一个元素");
		// 该订阅者在此处迭代请求。
		this.subscription.request(1);
	}

	@Override
	public void onError(Throwable throwable) {
		System.out.println(Thread.currentThread().getName() + ":Consumer 2:异常");

	}

	@Override
	public void onComplete() {
		System.out.println(Thread.currentThread().getName() + ":Consumer 2:完成");
	}

}

五、订阅者3

仅仅在注册时请求3个元素

package xyz.jangle.thread.test.n6_x.subscriber;

import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.Flow.Subscription;

/**
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年9月9日 下午4:59:27
 * 
 */
public class Consumer3 implements Subscriber<Item> {
	
	private Subscription subscription;

	@Override
	public void onSubscribe(Subscription subscription) {
		// 当该对象被订阅到发布者中时,该方法被调用
		System.out.println(Thread.currentThread().getName()+":Consumer 3:收到订阅(subscription)无Item请求");
		this.subscription = subscription;
		// 该订阅者只请求3个
		this.subscription.request(3);
	}

	@Override
	public void onNext(Item item) {
		// 发布者有新元素被请求时,该方法被调用。
		System.out.println(Thread.currentThread().getName()+":Consumer 3:onNext方法: "+item.getTitle()+","+item.getContent());
	}

	@Override
	public void onError(Throwable throwable) {
		System.out.println(Thread.currentThread().getName()+":Consumer 3:异常");
		throwable.printStackTrace(System.err);
	}

	@Override
	public void onComplete() {
		System.out.println(Thread.currentThread().getName()+":Consumer 3:完成");
	}
	
	public void request(long n) {
		this.subscription.request(n);
	}

}

六、执行结果

ForkJoinPool.commonPool-worker-3:Consumer 1: 收到订阅(subscription)无Item请求
ForkJoinPool.commonPool-worker-7:Consumer 3:收到订阅(subscription)无Item请求
ForkJoinPool.commonPool-worker-5:Consumer 2: 收到订阅(subscription),请求一个Item
ForkJoinPool.commonPool-worker-5:Consumer 2:onNext方法:title 0,这个是Item的内容0...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 3:onNext方法: title 0,这个是Item的内容0
ForkJoinPool.commonPool-worker-5:Consumer 3:onNext方法: title 1,这个是Item的内容1
ForkJoinPool.commonPool-worker-9:Consumer 2:onNext方法:title 1,这个是Item的内容1...并请求下一个元素
ForkJoinPool.commonPool-worker-5:Consumer 3:onNext方法: title 2,这个是Item的内容2
ForkJoinPool.commonPool-worker-9:Consumer 2:onNext方法:title 2,这个是Item的内容2...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 2:onNext方法:title 3,这个是Item的内容3...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 2:onNext方法:title 4,这个是Item的内容4...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 2:onNext方法:title 5,这个是Item的内容5...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 2:onNext方法:title 6,这个是Item的内容6...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 2:onNext方法:title 7,这个是Item的内容7...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 2:onNext方法:title 8,这个是Item的内容8...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 2:onNext方法:title 9,这个是Item的内容9...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 3:onNext方法: title 3,这个是Item的内容3
ForkJoinPool.commonPool-worker-9:Consumer 3:onNext方法: title 4,这个是Item的内容4
ForkJoinPool.commonPool-worker-5:Consumer 2:onNext方法:last title,last context...并请求下一个元素
ForkJoinPool.commonPool-worker-9:Consumer 3:onNext方法: title 5,这个是Item的内容5
ForkJoinPool.commonPool-worker-5:Consumer 2:完成

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值