专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

CompletableFuture实现异步编排全面分析和总结

  一、CompletableFuture简介CompletableFuture结合了Future的优点,提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了转换和组合CompletableFuture的方法。
  CompletableFuture被设计在Java中进行异步编程。异步编程意味着在主线程之外创建一个独立的线程,与主线程分隔开,并在上面运行一个非阻塞的任务,然后通知主线程进展,成功或者失败。
  CompletableFuture是由Java8引入的,在Java8之前我们一般通过Future实现异步。
  Future用于表示异步计算的结果,只能通过阻塞或者轮询的方式获取结果,而且不支持设置回调方法,Java8之前若要设置回调一般会使用guava的ListenableFuture。CompletableFuture对Future进行了扩展,可以通过设置回调的方式处理计算结果,同时也支持组合操作,支持进一步的编排,同时一定程度解决了回调地狱的问题。本文的名词缩写:CF:代表CompletableFutureCS:代表CompletionStage二、CompletableFuture核心接口API介绍2。1Future使用Future局限性
  从本质上说,Future表示一个异步计算的结果。它提供了isDone()来检测计算是否已经完成,并且在计算结束后,可以通过get()方法来获取计算结果。在异步计算中,Future确实是个非常优秀的接口。但是,它的本身也确实存在着许多限制:并发执行多任务:Future只提供了get()方法来获取结果,并且是阻塞的。所以,除了等待你别无他法;无法对多个任务进行链式调用:如果你希望在计算任务完成后执行特定动作,比如发邮件,但Future却没有提供这样的能力;无法组合多个任务:如果你运行了10个任务,并期望在它们全部执行结束后执行特定动作,那么在Future中这是无能为力的;没有异常处理:Future接口中没有关于异常处理的方法;
  方法
  说明
  描述
  boolean
  cancel(booleanmayInterruptIfRunning)
  尝试取消执行此任务。
  V
  get()
  如果需要等待计算完成,然后检索其结果。
  V
  get(longtimeout,TimeUnitunit)
  如果需要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。
  boolean
  isCancelled()
  如果此任务在正常完成之前取消,则返回true。
  boolean
  isDone()
  如果此任务完成,则返回true。2。2CompletableFuturepublicclassCompletableFutureTimplementsFutureT,CompletionStageT{}
  JDK1。8才新加入的一个实现类CompletableFuture,而CompletableFuture实现了两个接口(如上面代码所示):Future、CompletionStagestrongem,意味着可以像以前一样通过阻塞或者轮询的方式获得结果。
  Future表示异步计算的结果,CompletionStage用于表示异步执行过程中的一个步骤Stage,这个步骤可能是由另外一个CompletionStage触发的,随着当前步骤的完成,也可能会触发其他一系列CompletionStage的执行。从而我们可以根据实际业务对这些步骤进行多样化的编排组合,CompletionStage接口正是定义了这样的能力,我们可以通过其提供的thenAppy、thenCompose等函数式编程方法来组合编排这些步骤。CompletableFuture是Future接口的扩展和增强。CompletableFuture实现了Future接口,并在此基础上进行了丰富地扩展,完美地弥补了Future上述的种种问题。更为重要的是,CompletableFuture实现了对任务的编排能力。借助这项能力,我们可以轻松地组织不同任务的运行顺序、规则以及方式。从某种程度上说,这项能力是它的核心能力。而在以往,虽然通过CountDownLatch等工具类也可以实现任务的编排,但需要复杂的逻辑处理,不仅耗费精力且难以维护。2。3CompletionStage
  CompletionStage接口提供了更多方法来更好的实现异步编排,并且大量的使用了JDK8引入的函数式编程概念。由stage执行的计算可以表示为Function,Consumer或Runnable(使用名称分别包括apply、accept或run的方法),具体取决于它是否需要参数和或产生结果。例如:stage。thenApply(xsquare(x))。thenAccept(xSystem。out。print(x))。thenRun(()System。out。println());三、使用CompletableFuture场景3。1应用场景
  1执行比较耗时的操作时,尤其是那些依赖一个或多个远程服务的操作,使用异步任务可以改善程序的性能,加快程序的响应速度;
  2使用CompletableFuture类,它提供了异常管理的机制,让你有机会抛出、管理异步任务执行种发生的异常;
  3如果这些异步任务之间相互独立,或者他们之间的的某一些的结果是另一些的输入,你可以讲这些异步任务构造或合并成一个。
  举个常见的案例,在APP查询首页信息的时候,一般会涉及到不同的RPC远程调用来获取很多用户相关信息数据,比如:商品banner轮播图信息、用户message消息信息、用户权益信息、用户优惠券信息等,假设每个rpcinvoke()耗时是250ms,那么基于同步的方式获取到话,算下来接口的RT至少大于1s,这响应时长对于首页来说是万万不能接受的,因此,我们这种场景就可以通过多线程异步的方式去优化。
  3。2CompletableFuture依赖链分析
  根据CompletableFuture依赖数量,可以分为以下几类:零依赖、单依赖、双重依赖和多重依赖。
  零依赖
  下图Future1、Future2都是零依赖的体现:
  单依赖:仅依赖于一个CompletableFuture
  下图Future3、Future5都是单依赖的体现,分别依赖于Future1和Future2:
  双重依赖:同时依赖于两个CompletableFuture
  下图Future4即为双重依赖的体现,同时依赖于Future1和Future2:
  多重依赖:同时依赖于多个CompletableFuture
  下图Future6即为多重依赖的体现,同时依赖于Future3、Future4和Future5:
  类似这种多重依赖的流程来说,结果依赖于三个步骤:Future3、Future4、Future5,这种多元依赖可以通过allOf()或anyOf()方法来实现,区别是当需要多个依赖全部完成时使用allOf(),当多个依赖中的任意一个完成即可时使用anyOf(),如下代码所示:CompletableFutureVoidFuture6CompletableFuture。allOf(Future3,Future4,Future5);CompletableFutureStringresultFuture6。thenApply(v{这里的join并不会阻塞,因为传给thenApply的函数是在Future3、Future4、Future5全部完成时,才会执行。result3Future3。join();result4Future4。join();result5Future5。join();返回result3、result4、result5组装后结果returnassamble(result3,result4,result5);});四、CompletableFuture异步编排
  在分析CompletableFuture异步编排之前,我跟大家理清一下CompletionStage接口下(thenRun、thenApply、thenAccept、thenCombine、thenCompose)、(handle、whenComplete、exceptionally)相关方法的实际用法和它们之间的区别是什么?带着你的想法往下看吧!!!4。1《异步编排API》thenRun:【执行】直接开启一个异步线程执行任务,不接收任何参数,回调方法没有返回值;thenApply:【提供】可以提供返回值,接收上一个任务的执行结果,作为下一个Future的入参,回调方法是有返回值的;thenAccept:【接收】可以接收上一个任务的执行结果,作为下一个Future的入参,回调方法是没有返回值的;thenCombine:【结合】可以结合不同的Future的返回值,做为下一个Future的入参,回调方法是有返回值的;thenCompose:【组成】将上一个Future实例结果传递给下一个实例中。异步回调建议使用自定义线程池线程池配置author:austinsince:20233121:32ConfigurationpublicclassThreadPoolConfig{Bean中声明的value不能跟定义的实例同名Bean(valuecustomAsyncTaskExecutor)publicThreadPoolTaskExecutorasyncThreadPoolExecutor(){ThreadPoolTaskExecutorthreadPoolTaskExecutornewThreadPoolTaskExecutor();threadPoolTaskExecutor。setCorePoolSize(5);threadPoolTaskExecutor。setMaxPoolSize(10);threadPoolTaskExecutor。setKeepAliveSeconds(60);threadPoolTaskExecutor。setQueueCapacity(2048);threadPoolTaskExecutor。setWaitForTasksToCompleteOnShutdown(true);threadPoolTaskExecutor。setThreadNamePrefix(customAsyncTaskExecutor);threadPoolTaskExecutor。setRejectedExecutionHandler(newThreadPoolExecutor。CallerRunsPolicy());returnthreadPoolTaskExecutor;}Bean(valuethreadPoolExecutor)publicThreadPoolExecutorthreadPoolExecutor(){ThreadPoolExecutorthreadPoolExecutornewThreadPoolExecutor(10,10,60L,TimeUnit。SECONDS,newArrayBlockingQueue(10000),newThreadPoolExecutor。CallerRunsPolicy());returnthreadPoolExecutor;}}
  如果所有异步回调都会共用该CommonPool,核心与非核心业务都竞争同一个池中的线程,很容易成为系统瓶颈。手动传递线程池参数可以更方便的调节参数,并且可以给不同的业务分配不同的线程池,以求资源隔离,减少不同业务之间的相互干扰。所以,强烈建议你要根据不同的业务类型创建不同的线程池,以避免互相干扰。通过自定义线程池customAsyncTaskExecutor,后面不同的异步编排方法,我们可以通过指定对应的线程池。1runAsync()、thenRun()RestControllerpublicclassCompletableFutureCompose{ResourceprivateThreadPoolTaskExecutorcustomAsyncTaskExecutor;RequestMapping(valuethenRun)publicvoidthenRun(){CompletableFuture。runAsync((){System。out。println(threadname:Thread。currentThread()。getName()firststep。。。);},customAsyncTaskExecutor)。thenRun((){System。out。println(threadname:Thread。currentThread()。getName()secondstep。。。);})。thenRunAsync((){System。out。println(threadname:Thread。currentThread()。getName()thirdstep。。。);});}}
  接口输出结果:threadname:customAsyncTaskExecutor1firststep。。。threadname:customAsyncTaskExecutor1secondstep。。。threadname:ForkJoinPool。commonPoolworker3thirdstep。。。2thenApply()RequestMapping(valuethenApply)publicvoidthenApply(){CompletableFuture。supplyAsync((){System。out。println(threadname:Thread。currentThread()。getName()firststep。。。);returnhello;},customAsyncTaskExecutor)。thenApply((result1){StringtargetResultresult1austin;System。out。println(firststepresult:result1);System。out。println(threadname:Thread。currentThread()。getName()secondstep。。。,targetResult:targetResult);returntargetResult;});}
  接口输出结果:threadname:customAsyncTaskExecutor2firststep。。。firststepresult:hellothenApply虽然没有指定线程池,但是默认是复用它上一个任务的线程池的threadname:customAsyncTaskExecutor2secondstep。。。,targetResult:helloaustin3thenAccept()RequestMapping(valuethenAccept)publicvoidthenAccept(){CompletableFuture。supplyAsync((){System。out。println(threadname:Thread。currentThread()。getName()firststep。。。);returnhello;},customAsyncTaskExecutor)。thenAccept((result1){StringtargetResultresult1austin;System。out。println(firststepresult:result1);System。out。println(threadname:Thread。currentThread()。getName()secondstep。。。,targetResult:targetResult);});}
  接口输出结果:threadname:customAsyncTaskExecutor3firststep。。。firststepresult:hellothenAccept在没有指定线程池的情况下,并未复用它上一个任务的线程池threadname:httpnio10032exec9secondstep。。。,targetResult:helloaustin
  thenAccept()和thenApply()的用法实际上基本上一致,区别在于thenAccept()回调方法是没有返回值的,而thenApply()回调的带返回值的。
  细心的朋友可能会发现,上面thenApply()和thenAccept()请求线程池在不指定的情况下,两者的不同表现,thenApply()在不指定线程池的情况下,会沿用上一个Future指定的线程池customAsyncTaskExecutor,而thenAccept()在不指定线程池的情况,并没有复用上一个Future设置的线程池,而是重新创建了新的线程来实现异步调用。4thenCombine()RequestMapping(valuethenCombine)publicvoidthenCombine(){CompletableFutureStringfuture1CompletableFuture。supplyAsync((){System。out。println(执行future1开始。。。);returnHello;},asyncThreadPoolExecutor);CompletableFutureStringfuture2CompletableFuture。supplyAsync((){System。out。println(执行future2开始。。。);returnWorld;},asyncThreadPoolExecutor);future1。thenCombine(future2,(result1,result2){Stringresultresult1result2;System。out。println(获取到future1、future2聚合结果:result);returnresult;})。thenAccept(resultSystem。out。println(result));}
  接口访问,打印结果:threadname:customAsyncTaskExecutor4执行future1开始。。。threadname:customAsyncTaskExecutor5执行future2开始。。。threadname:httpnio10032exec8获取到future1、future2聚合结果:HelloWorldHelloWorld复制代码5thenCompose()
  我们先有future1,然后和future2组成一个链:future1future2,然后又组合了future3,形成链:future1future2future3。这里有个隐藏的点:future1、future2、future3它们完全没有数据依赖关系,我们只不过是聚合了它们的结果。RequestMapping(valuethenCompose)publicvoidthenCompose(){CompletableFuture。supplyAsync((){第一个Future实例结果System。out。println(threadname:Thread。currentThread()。getName()执行future1开始。。。);returnHello;},customAsyncTaskExecutor)。thenCompose(result1CompletableFuture。supplyAsync((){将上一个Future实例结果传到这里System。out。println(threadname:Thread。currentThread()。getName()执行future2开始。。。,第一个实例结果:result1);returnresult1World;}))。thenCompose(result12CompletableFuture。supplyAsync((){将第一个和第二个实例结果传到这里System。out。println(threadname:Thread。currentThread()。getName()执行future3开始。。。,第一第二个实现聚合结果:result12);StringtargetResultresult12,Iamaustin!;System。out。println(最终输出结果:targetResult);returntargetResult;}));}
  接口访问,打印结果:threadname:customAsyncTaskExecutor1执行future1开始。。。threadname:ForkJoinPool。commonPoolworker3执行future2开始。。。,第一个实例结果:Hellothreadname:ForkJoinPool。commonPoolworker3执行future3开始。。。,第一第二个实现聚合结果:HelloWorld最终输出结果:HelloWorld,Iamaustin!Note:thenCombine()VSthenCompose(),两者之间的区别
  thenCombine结合的两个CompletableFuture没有依赖关系,且第二个CompletableFuture不需要等第一个CompletableFuture执行完成才开始。thenCompose()可以两个CompletableFuture对象,并将前一个任务的返回结果作为下一个任务的参数,它们之间存在着先后顺序。thenCombine()会在两个任务都执行完成后,把两个任务的结果合并。两个任务是并行执行的,它们之间并没有先后依赖顺序。4。2《CompletableFuture实例化创建》返回一个新的CompletableFuture,由线程池ForkJoinPool。commonPool()中运行的任务异步完成,不会返回结果。publicstaticCompletableFutureVoidrunAsync(Runnablerunnable);返回一个新的CompletableFuture,运行任务时可以指定自定义线程池来实现异步,不会返回结果。publicstaticCompletableFutureVoidrunAsync(Runnablerunnable,Executorexecutor);返回由线程池ForkJoinPool。commonPool()中运行的任务异步完成的新CompletableFuture,可以返回异步线程执行之后的结果。publicstaticUCompletableFutureUsupplyAsync(SupplierUsupplier);publicstaticUCompletableFutureUsupplyAsync(SupplierUsupplier,Executorexecutor);
  CompletableFuture有两种方式实现异步,一种是supply开头的方法,一种是run开头的方法:supply开头:该方法可以返回异步线程执行之后的结果;run开头:该方法不会返回结果,就只是执行线程任务。4。3《获取CompletableFuture结果》publicTget()publicTget(longtimeout,TimeUnitunit)publicTgetNow(TvalueIfAbsent)publicTjoin()publicCompletableFutureObjectallOf()publicCompletableFutureObjectanyOf()
  使用方式,演示:CompletableFutureIntegerfuturenewCompletableFuture();Integerintegerfuture。get();get():阻塞式获取执行结果,如果任务还没有完成则会阻塞等待知直到任务执行完成get(longtimeout,TimeUnitunit):带超时的阻塞式获取执行结果getNow():如果已完成,立刻返回执行结果,否则返回给定的valueIfAbsentjoin():该方法和get()方法作用一样,不抛异常的阻塞式获取异步执行结果allOf():当给定的所有CompletableFuture都完成时,返回一个新的CompletableFutureanyOf():当给定的其中一个CompletableFuture完成时,返回一个新的CompletableFutureNote:
  join()和get()方法都是阻塞式调用它们的线程(通常为主线程)来获取CompletableFuture异步之后的返回值。两者的区别在于join()返回计算的结果或者抛出一个unchecked异常CompletionException,而get()返回一个具体的异常。4。4《结果处理》
  当使用CompletableFuture异步调用计算结果完成、或者是抛出异常的时候,我们可以执行特定的Action做进一步处理,比如:publicCompletableFutureTwhenComplete(BiConsumerlt;?superT,?superThrowableaction)publicCompletableFutureTwhenCompleteAsync(BiConsumerlt;?superT,?superThrowableaction)publicCompletableFutureTwhenCompleteAsync(BiConsumerlt;?superT,?superThrowableaction,Executorexecutor)4。5《异常处理》
  使用CompletableFuture编写代码时,异常处理很重要,CompletableFuture提供了三种方法来处理它们:handle()、whenComplete()和exceptionly()。handle:返回一个新的CompletionStage,当该阶段正常或异常完成时,将使用此阶段的结果和异常作为所提供函数的参数执行,不会将内部异常抛出。whenComplete:返回与此阶段具有相同结果或异常的新CompletionStage,该阶段在此阶段完成时执行给定操作。与方法handle不同,会将内部异常往外抛出。exceptionally:返回一个新的CompletableFuture,CompletableFuture提供了异常捕获回调exceptionally,相当于同步调用中的trycatch。AutowiredprivateRemoteDictServiceremoteDictService;publicCompletableFutureDictgetDictDataAsync(longdictId){CompletableFutureDictResultresultFutureremoteDictService。findDictById(dictId);业务方法,内部会发起异步rpc调用returnresultFuture。exceptionally(error{通过exceptionally捕获异常,打印日志并返回默认值log。error(RemoteDictService。getDictDataAsyncExceptiondictId{},dictId,error);returnnull;});}handle()VSwhenComplete(),两者之间的区别核心区别在于whenComplete不消费异常,而handle消费异常Twomethodformssupportprocessingwhetherthetriggeringstagecompletednormallyorexceptionally:
  Method{whenComplete}allowsinjectionofanactionregardlessofoutcome,otherwisepreservingtheoutcomeinitscompletion。
  Method{handle}additionallyallowsthestagetocomputeareplacementresultthatmayenablefurtherprocessingbyotherdependentstages。
  翻译过来就是:
  两种方法形式支持处理触发阶段是否正常完成或异常完成:whenComplete:可以访问当前CompletableFuture的结果和异常作为参数,使用它们并执行您想要的操作。此方法并不能转换完成的结果,会内部抛出异常。handle:当此阶段正常或异常完成时,将使用此阶段的结果和异常作为所提供函数的参数来执行。当此阶段完成时,以该阶段的结果和该阶段的异常作为参数调用给定函数,并且函数的结果用于完成返回的阶段,不会把异常外抛出来。
  这里我通过代码演示一下:publicclassCompletableFutureExceptionHandler{publicstaticCompletableFuturehandle(inta,intb){returnCompletableFuture。supplyAsync(()ab)。handle((result,ex){if(null!ex){System。out。println(handleerror:ex。getMessage());return0;}else{returnresult;}});}publicstaticCompletableFuturewhenComplete(inta,intb){returnCompletableFuture。supplyAsync(()ab)。whenComplete((result,ex){if(null!ex){System。out。println(whenCompleteerror:ex。getMessage());}});}publicstaticvoidmain(String〔〕args){try{System。out。println(success:handle(10,5)。get());System。out。println(fail:handle(10,0)。get());}catch(Exceptione){System。out。println(catchexceptione。getMessage());}System。out。println();try{System。out。println(success:whenComplete(10,5)。get());System。out。println(fail:whenComplete(10,0)。get());}catch(Exceptione){System。out。println(catchexceptione。getMessage());}}}
  运行结果如下显示:success:2handleerror:java。lang。ArithmeticException:byzerofail:0success:2whenCompleteerror:java。lang。ArithmeticException:byzerocatchexceptionjava。lang。ArithmeticException:byzero
  可以看到,handle处理,当程序发生异常的时候,即便是catch获取异常期望输出,但是并未跟实际预想那样,原因是handle不会把内部异常外抛出来,而whenComplete会将内部异常抛出。五、CompletableFuture线程池须知Note:关于异步线程池(十分重要)
  异步回调方法可以选择是否传递线程池参数Executor,这里为了实现线程池隔离,当不传递线程池时,默认会使用ForkJoinPool中的公共线程池CommonPool,这个线程池默认创建的线程数是CPU的核数,如果所有的异步回调共享一个线程池,核心与非核心业务都竞争同一个池中的线程,那么一旦有任务执行一些很慢的IO操作,就会导致线程池中所有线程都阻塞在IO操作上,很容易成为系统瓶颈,影响整个系统的性能。因此,建议强制传线程池,且根据实际情况做线程池隔离,减少不同业务之间的相互干扰。六、基于CompletableFuture实现接口异步revoke案例实现Controller层RestControllerRequestMapping(index)publicclassIndexWebController{ResourceprivateThreadPoolExecutorasyncThreadPoolExecutor;RequestMapping(valuehomeIndex,method{RequestMethod。POST,RequestMethod。GET})publicStringhomeIndex(RequestParam(requiredfalse)StringuserId,RequestParam(valuelang)Stringlang){ResultDataHomeVOresultnewResultData();获取Banner轮播图信息CompletableFutureListBannerVOfuture1CompletableFuture。supplyAsync(()this。buildBanners(userId,lang),asyncThreadPoolExecutor);获取用户message通知信息CompletableFutureNotificationVOfuture2CompletableFuture。supplyAsync(()this。buildNotifications(userId,lang),asyncThreadPoolExecutor);获取用户权益信息CompletableFutureListBenefitVOfuture3CompletableFuture。supplyAsync(()this。buildBenefits(userId,lang),asyncThreadPoolExecutor);获取优惠券信息CompletableFutureListCouponVOfuture4CompletableFuture。supplyAsync(()this。buildCoupons(userId),asyncThreadPoolExecutor);CompletableFutureVoidallOfFutureCompletableFuture。allOf(futrue1,futrue2,futrue3,future4);HomeVofinalHomeVOhomeVO;CompletableFutureHomeVOresultFutureallOfFuture。thenApply(v{try{finalHomeVo。setBanners(future1。get());finalHomeVo。setNotifications(future2。get());finalHomeVo。setBenefits(future3。get());finalHomeVo。setCoupons(future4。get());returnfinalHomeVO;}catch(Exceptione){logger。error(〔Error〕assemblehomeVOdataerror:{},e);thrownewRuntimeException(e);}});homeVOresultFuture。join();result。setData(homeVO);returnwriteJson(result);}}Service层SneakyThrowspublicListBannerVObuildBanners(StringuserId,Stringlang){模拟请求耗时0。5秒Thread。sleep(500);returnnewListBannerVO();}SneakyThrowspublicListNotificationVObuildNotifications(StringuserId,Stringlang){模拟请求耗时0。5秒Thread。sleep(500);returnnewListNotificationVO();}SneakyThrowspublicListBenefitVObuildBenefits(StringuserId,Stringlang){模拟请求耗时0。5秒Thread。sleep(500);returnnewListBenefitVO();}SneakyThrowspublicListCouponVObuildCoupons(StringuserId){模拟请求耗时0。5秒Thread。sleep(500);returnnewListCouponVO();}六、异步化带来的性能提升通过异步化改造,原本同步获取数据的API性能得到明显提升,大大减少了接口的响应时长(RT)。接口的吞吐量大幅度提升。七、总结
  本篇文章主要是介绍了CompletableFuture使用原理和相关不同方法的场景化使用,以及通过不同的实例演示了异步回调的过程,好了,今天的分享就到此结束了,如果文章对你有所帮助,欢迎点赞评论收藏,

2022年铜川市事业单位公开招聘工作人员面试资格复审相关事项公告根据2022年铜川市事业单位公开招聘工作人员公告规定,现将本次招聘笔试成绩最低分数线和资格复审有关事项公告如下一笔试成绩最低分数线为确保招聘人员素质,本次招聘笔试成绩最低分数线为82017年,浙江典当行遭遇抢劫,警方千里追凶,凶手微信牵出案中案2017年,在云南砚山,最近胡家人的心头被一个问题所笼罩他们家的女儿胡梅(化名)和丈夫李军(化名)去了深圳打工,已经走了三个月了,但是胡梅也不知道为何,从来不和家里人开视频,甚至连2015年,山东池塘发现母女两人尸体,警方调查后,发现背后隐情如果说是长时间,尸体在水底下不浮上来,一般来讲应该是有坠尸的物体,如果说是坠尸入水的话,那很可能就是一个刑事案子。2015年5月,山东省临沭县公安局接到附近民众报案,有村民在当地的一大学生为唐山打人男子辩解,态度强硬,让被打女子反思?唐山打人事件仿佛是冬夜里的一声惊雷,让大家惊讶不已。因为此事性质之恶劣让人是在难以想象,更难以接受。得益于网络曝光的监控视频,才让大家更加清楚当晚究竟发生了什么,以及谁是谁非。从监发现动脉硬化斑块,就要长期吃他汀和阿司匹林?专家说出不同观点如果问发现动脉粥样硬化斑块的最简单方法是什么,那么通过颈动脉彩超检查,结合颈动脉内中膜增厚程度以及其他特征,初步判断颈动脉斑块问题,应该是最普遍和便捷的方法了。颈动脉出现了斑块,我上外男生竟在图书馆给女子咖啡里投放异物6月13日,上海警方针对上海外国语大学一女生饮料中被他人投放发牛磺酸泡腾片寄予通报6月12日,上外学生尹某某(男,21岁)在图书馆内趁女生离开座位之际,向其咖啡杯中投放异物。该女生唐山被打女孩伤情如何?医院科室人员不肯透露,安保人员说了实话唐山烧烤店女孩被一群男子围殴的视频在网上引发了热议,视频中一位白衣女子受到绿衣男子的性骚扰,女孩反抗后绿衣男和同伴对其暴打,同桌的其他女孩为了保护白衣女孩也被殴打,视频中白衣女被啤唐山女子砸下去的酒瓶即使是正当防卫,也不应该鼓励唐山多名男子光天化日之下骚扰殴打多名女子,让全国人民义愤填膺,毫无疑问,在法律的范围内,无论怎么重判这几名男子,本人都表示支持。但对于一些细节,还是想发表以下自己的看法,视频显示,别误导学生了,女老师下班后去蹦迪,手机上的内容却格格不入导语教师究竟是一种信仰还是一份工作,很多人都为此感到困惑不解,如果说几十年前的教师是满怀激情地投入到教育工作中,那么现在的教师就是一群丧失了教育热情的工作机器。他们只知道这是一份工吉利杀入智能手机行业控股魅族李书福难掩新能源领域焦虑雷递网雷建平6月13日报道传闻数月后,吉利收购魅族一事终于获得证实。6月13日,国家市场监管总局发布了一则案件公示。公示信息显示,湖北星纪时代科技有限公司(简称星纪时代)与珠海市魅华为手机鸿蒙系统隐藏了9个实用功能,长按2秒自动开启,太厉害了华为手机鸿蒙系统其实还隐藏和很多实用功能,每一个都非常好用,但是往往会被大家所忽略。今天帮大家整理了全网最全的关于华为手机长按2秒隐藏的实用功能,绝对有你不知道的功能,建议大家点赞
萨尔浒之战明军丧师十万,努尔哈赤一战奠定大清之基在整个清朝建立的过程中,有几场至关重要的战役,这几场战役改变了明清之间的实力对比,其中最重要的一场战役就是明朝与后金之间的萨尔浒之战。此战奠定了清朝的崛起。明朝后期朝政日益腐败,嘉官运亨通的于振甲,无定河改永定河的促成者天下长河征文知县于振甲竟被饥饿逼成绿林好汉揭竿而起了,这一段很滑稽包括陈潢自投罗网提议抢粮的有关剧情,有点儿荒唐,也不咋逻辑陈潢该急于回去复命啊史实中的于振甲于成龙以及于北溟于成龙一个朝代的覆灭清朝是距我国最后一个封建王朝,其实说起清朝的灭亡,并不是只因为八国联军列强侵略。就像红楼梦里所说若从外头杀来,一时是杀不死的。这可是古人说的,百足之虫,死而不僵,必须先从家里自杀自有东征西征南征,为何只有向北叫做北伐?在看历史剧时常可看到北伐这个词,例如诸葛亮五次北伐宋朝岳飞北伐等不过,令人纳闷的是,古代其它方向的作战都叫征,如东征西征南征,为何唯独向北作战时叫做伐呢?这背后有何含意?诸葛亮曾五广西台办普法宣讲组走进钦州台胞点赞及时解渴普法维权宣讲(图片来源广西钦州市)中国台湾网11月25日讯近日,广西台办普法宣讲组走进钦州举办台胞普法维权宣讲系列活动,宣介二十大精神,在钦台胞台商陆配和钦州市台办系统干部有关市直贵州切实把学习成果转化为强大动力近日,学习宣传贯彻党的二十大精神贵州省委宣讲团在全省工商联系统开展宣讲。贵州省委宣讲团成员省委统战部副部长省工商联党组书记李岳德作宣讲报告。李岳德紧扣深入学习宣传贯彻党的二十大精神刷屏时代审计人如何读书随着万物互联和智能的到来,纸质图书阅读越来越少,在习惯了刷屏时代的点点划划后,灯下展卷的悠然不再偷得浮生半日闲的心境亦不再,取而代之的是手足无措的焦虑和功名万里忙如燕的浮躁。你是否22年前浙江首例连体婴分离,成功闯过6次手术的妹妹,现在如何了文菁妈2000年5月28日,福建一个孕妇生下了一对像双胞胎又不是双胞胎的孩子,这两个孩子确实同时怀在妈妈的体内,但是他们出生的时候却没有完全的分离,从肚脐到会阴是连在一起的,在医学不节食不反弹,产后jamu被动躺收没有一位妈妈产后不想立马瘦下去的,所以有的妈妈会采取比较极端的做法,比如节食疯狂运动各种瘦身衣等轮番上阵。但殊不知,通过这些方法可能会对自己的产后身体造成更大的损伤!一不小心本身原以情换心心理疏导让监测户立志振作红网时刻张家界11月24日讯(通讯员董海旭)谢谢你们,让我觉得没有被抛弃,我要振作起来加油干,为家里的小孩和老人撑起一片天。慈利县三官寺新民村监测户唐某送别时主动握起帮扶干部的手,北青连续两场任第四官员后,马宁有望第二轮上演世界杯主哨首秀直播吧11月24日讯据北京青年报报道,小组赛首轮两次担任第四官员的马宁,非常有望在小组赛第2轮迎来其主哨世界杯正赛的首秀。继以第四官员身份执法卡塔尔世界杯小组赛首轮B组威尔士队vs
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网