Java handle用法
JAVA响应式编程reactor中如果需要对一个flux中的数据进行提前返回 可以使用handle
具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | @GetMapping ( "/a" ) public Mono<object data-origwidth= "" data-origheight= "" style= "width: 1264px;" > a() throws InterruptedException { long begin = System.currentTimeMillis(); Mono m5 = Mono.just( "" ).map(s -> { try { TimeUnit.SECONDS.sleep( 5 ); System.out.println( "5" ); System.out.println(System.currentTimeMillis() - begin); } catch (InterruptedException e) { e.printStackTrace(); } return "5" ; }).subscribeOn(Schedulers.boundedElastic()); Mono m8 = Mono.just( "" ).map(s -> { try { TimeUnit.SECONDS.sleep( 8 ); System.out.println( "8" ); System.out.println(System.currentTimeMillis() - begin); } catch (InterruptedException e) { e.printStackTrace(); } return "8" ; }).subscribeOn(Schedulers.boundedElastic()); Mono m10 = Mono.just( "" ).map(s -> { try { TimeUnit.SECONDS.sleep( 15 ); System.out.println( "15" ); System.out.println(System.currentTimeMillis() - begin); } catch (Exception e) { e.printStackTrace(); } return "15" ; }).subscribeOn(Schedulers.boundedElastic()); Mono<object data-origwidth= "" data-origheight= "" style= "width: 524px;" > single = Flux.merge(m8, m5, m10).handle(((s, synchronousSink) -> { if ( "8" .equals(s)) { synchronousSink.next( "卢本伟牛" ); synchronousSink.complete(); } })).defaultIfEmpty( "null" ).single(); return single; } </object></object> |
subscribeOn(Schedulers.boundedElastic())是让这些mono进行异步处理
上述定义了3个Mono进行请求 使用Sleep进行模拟请求中业务处理耗时
m5是需要执行3s m8是需要执行8s m10是需要执行15s
如果我们有多个耗时处理的请求 需要同时请求 然后又需要合并结果 并且返回我们需要的结果 进行提前返回。
例如:我需要同时请求这些接口 当8这个接口有结果返回的时候 由于其他请求时间太长了 需要提前返回一个值 放弃其他结果处理 所以我们可以进行判断.
1 2 3 4 5 6 7 8 9 10 11 12 | //这个s代表前面传入的元素 执行完会传入这个handle // synchronousSink.next() 代表我执行完这个流返回给下一个进行处理 next(Object) // synchronousSink.complete(); 代表我们执行完取消其他的流 Flux.merge(m8, m5, m10).handle(((s, synchronousSink) -> { if ( "8" .equals(s)) { synchronousSink.next( "卢本伟牛" ); synchronousSink.complete(); } })).subscribe(s -> { System.err.println(s); }); |
由于上面当s为8的时候 将卢本伟牛传入下一个流 然后执行完成 所以还有个m10不会执行完 就会直接丢弃
我们进行测试
发现控制台打印
我们如果使用传统的mvc执行m5我们会耗时5s m8会耗时8s 加起来就是13s
我们使用响应式编程则只会耗时8s 当如果多个耗时操作拼接在一起 我们需要多个返回结果的时候我们可以使用handle进行提前返回
返回结果为卢本伟牛 也就是我们之前当s为8时执行的 ,synchronousSink.next(“卢本伟牛”);,将这个字符串传给最终结果的流,当然我们也可以根据自己的逻辑 发放多个synchronousSink.next。
handle的标准使用方式
在Java语言中,直接将handle声明为Activity的内部类去使用handle,非静态内部类会持有外部类的一个隐试引用,这样就可能造成外部类无法被垃圾回收,从而导致内存泄漏。
故而,给出规范的handle使用方式如下:
handle的基类
1 2 3 4 5 6 7 8 9 10 11 12 | public class UIHandler extends Handler{ protected WeakReference ref; public UIHandler(T cla){ ref = new WeakReference(cla); } public T getRef(){ return ref != null ? ref.get() : null ; } } |
handle运用实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | public class MainActivity extends Activity{ private final MainHandler mHandler = new MainHandler( this ); @Override protected void onCreate(Bundle savedInstanceState){ super .oncreate(savedInstanceState); setContentView(R.layout.activity_main); mHandler.post(mRunnable); } private static final Runnable mRunnable = new Runnable(){ @Override public void run(){ } }; private class MainHandler extends UIHandler{ private MainHandler(MainActivity activity){ super (activity); } @Override public void handleMessage(Message msg){ super .handleMessage(msg); MainActivity activity = (MainActivity)ref.get(); if (activity != null ){ if (activity.isFinishing() return ; switch (msg.what){ case 1 : break ; } } } } } |
以上为个人经验,希望能给大家一个参考,也希望大家多多支持IT俱乐部。