当前位置: 首页 > news >正文

微信上优惠券的网站怎么做的徐汇网站建设

微信上优惠券的网站怎么做的,徐汇网站建设,做网站制作一般多少钱,中国在建工程信息网文章目录 线程池 Runnable/Callable线程池 FutureCompletableFuture线程池 Async注解Spring 事件创建事件事件发布者事件监听器调用事件 消息队列生产者消费者 在实际开发中有些耗时操作,或者对主流程不是那么重要的逻辑,可以通过异步的方式去执行&am…

文章目录

  • 线程池 + Runnable/Callable
  • 线程池 + Future
  • CompletableFuture
  • 线程池 + @Async注解
  • Spring 事件
    • 创建事件
    • 事件发布者
    • 事件监听器
    • 调用事件
  • 消息队列
    • 生产者
    • 消费者

在实际开发中有些耗时操作,或者对主流程不是那么重要的逻辑,可以通过异步的方式去执行,从而提高主逻辑的效率。常见的场景比如下单成功后短信或者小程序内通知用户,这个过程其实可以走异步,最坏的情况是没通知到用户,这个情况是可以接受的,只要下单成功了就行。下面介绍几种常见的异步编程的方式:
PS:忽略下方创建线程池的方式,主要看如何实现异步编程

线程池 + Runnable/Callable

这种方式在主线程中引入线程池,通过线程池进行异步操作。

public class AsyncThread{private static ExecutorService executorService = Executors.newSingleThreadExecutor();public static void main(String[] args) {System.out.println("主线程开始");executorService.submit(() -> {System.out.println("这是一个异步线程");});System.out.println("主线程结束");}
}-- 控制台打印结果
主线程开始
主线程结束
这是一个异步线程

可能有人有疑问为什么不直接new Thread(),主要原因是频繁创建线程,销毁非常耗费系统资源。线程池是池化技术,可以更好的管理池内线程的生命周期。但是这种实现方式不能满足一些特殊场景,比如需要异步任务的返回值

线程池 + Future

Future是JUC并发包提供的,它的出现解决了异步任务需要返回值的问题。

public class FutureTest {ExecutorService executorService = Executors.newFixedThreadPool(1);public static void main(String[] args) {System.out.println("主线程开始");new FutureManager().execute();System.out.println("主线程结束");}@SneakyThrowspublic String execute() {Future<String> future = executorService.submit(new Callable<String>() {@Overridepublic String call() throws Exception {System.out.println("这是一个异步线程开始");Thread.sleep(2000);System.out.println("这是一个异步线程结束");return "这是一个异步线程返回的结果";}});String result = "默认返回值";// 放开注释,会阻塞主线程
//        result = future.get();return result;}
}-- 不获取结果 控制台打印结果
主线程开始
主线程结束
这是一个异步线程开始
这是一个异步线程结束-- 阻塞获取结果 控制台打印结果
主线程开始
这是一个异步线程开始
这是一个异步线程结束
主线程结束

Future虽然可以获得异步任务的结果,但是缺点也很明显,主要缺点如下:

  1. 获取结果需要阻塞主线程
  2. 异步任务出现异常,主线程无法感知
  3. 多个Future之间相互独立,如果多个异步任务的返回值有依赖关系,就不能满足需求

CompletableFuture

CompletableFuture也是JUC并发包中的类,它可以让多个Future进行编排。

public class CompletableFutureTest {/*** thenAccept子任务和父任务公用同一个线程*/@SneakyThrowspublic static void thenRunAsync() {CompletableFuture<Integer> fristFuture = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread() + " fristFuture ....");try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}return 1;});CompletableFuture<Void> secondFuture = fristFuture.thenRunAsync(() -> {System.out.println(Thread.currentThread() + " secondFuture ...");});//等待任务1执行完成System.out.println("fristFuture结果->" + fristFuture.get());//等待任务2执行完成System.out.println("secondFuture结果->" + secondFuture.get());}public static void main(String[] args) {System.out.println("主线程开始");thenRunAsync();System.out.println("主线程结束");}}-- 控制台打印结果
主线程开始
Thread[ForkJoinPool.commonPool-worker-3,5,main] fristFuture ....
Thread[ForkJoinPool.commonPool-worker-5,5,main] secondFuture ...
fristFuture结果->1
secondFuture结果->null
主线程结束

以上示例fristFuture与secondFuture两个任务简历联系,后者需要前者执行完在执行。可以实际运行一下看下效果。大概流程是示例代码的11行会阻塞在那里,而不会先打印Thread[ForkJoinPool.commonPool-worker-5,5,main] secondFuture … 原因是secondFuture依赖于fristFuture,fristFuture执行结束后才会往下执行。

CompletableFuture没有配合线程池使用的原因是,CompletableFuture默认使用的是ForkJoinPool.commonPool,从打印的结果可以清楚的看出来。ForkJoinPool的好处是可以自己管理线程池,当没有太多任务需要执行时,它会自己关闭一些线程,释放资源。

线程池 + @Async注解

**@Async注解建议配合线程池使用,使用时没有指定线程池,会使用默认的SimpleAsyncTaskExecutor,它并不是真正的线程池,每次都是创建新的线程执行任务,不会复用线程。最主要的是它没最大线程数的限制,并发大的时候容易产生性能问题。**下面是一个示例:

首先需要自定义一个线程池,加上@EnableAsync和@Configuration,这样可以不用在启动类上加@EnableAsync。

@EnableAsync
@Configuration
public class TaskPoolConfig {@Bean("taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();threadPoolTaskExecutor.setCorePoolSize(Runtime.getRuntime().availableProcessors());threadPoolTaskExecutor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 2);threadPoolTaskExecutor.setQueueCapacity(100);threadPoolTaskExecutor.setKeepAliveSeconds(60);threadPoolTaskExecutor.setThreadNamePrefix("taskExecutor-");threadPoolTaskExecutor.setAwaitTerminationSeconds(60);threadPoolTaskExecutor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());return threadPoolTaskExecutor;}
}

在需要异步的方法上加上@Async注解,并指定线程池即可。

@Service
public class AsyncServiceImpl implements AsyncService {@Override@Async("taskExecutor")public MessageResult sendSms(String callPrefix, String mobile, String actionType, String content) {// 业务逻辑}}

Spring 事件

Spring的事件原理是在某个地方抛出一个事件,通过Spring的监听机制监听到该事件,进而做出业务逻辑的处理。这个过程需要有3个步骤:创建事件,发布事件,监听事件。

创建事件

首先,我们创建一个自定义的事件,继承自ApplicationEvent:

import org.springframework.context.ApplicationEvent;public class MyEvent extends ApplicationEvent {public MyEvent(Object source) {super(source);}
}

事件发布者

然后,我们创建一个事件发布者,它会发布我们刚刚创建的MyEvent事件:

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;@Component
public class MyEventPublisher {private final ApplicationEventPublisher applicationEventPublisher;public MyEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}public void publishEvent() {MyEvent myEvent = new MyEvent(this);applicationEventPublisher.publishEvent(myEvent);}
}

事件监听器

接下来,我们创建一个事件监听器,它会监听并处理我们的MyEvent事件:

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@Component
public class MyEventListener {@EventListenerpublic void handleMyEvent(MyEvent event) {System.out.println("MyEvent received");}
}

调用事件

在主程序中调用事件发布者的publishEvent方法来发布事件:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Main {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(MyEventPublisher.class);context.register(MyEventListener.class);context.refresh();MyEventPublisher publisher = context.getBean(MyEventPublisher.class);publisher.publishEvent();}
}

消息队列

消息队列在异步的场景下使用非常的广泛。以下以RabbitMQ为例。

生产者

@Component
public class Producer {@AutowiredAmqpTemplate amqpTemplate;public void sendCallbackMessage(MessageRequest message) {amqpTemplate.convertAndSend(QueueEnum.QUEUE_NAME.getExchange(), QueueEnum.QUEUE_NAME.getRoutingKey(), JSONObject.toJsonString(message), new MessagePostProcessor() {@Overridepublic Message postProcessMessage(Message message) throws Exception {// xxxxxreturn message;}});}
}

消费者

@Component
@RabbitListener(queues = "message.order", containerFactory = "listenerContainerFactory")
public class Consumer {@RabbitHandlerpublic void handle(String json, Channel channel, @Headers Map<String, Object> map) throws Exception {// 校验逻辑,比如业务校验,请求头检验try {        //执行业务逻辑//消息消息成功手动确认,对应消息确认模式acknowledge-mode: manualchannel.basicAck((Long) map.get(Headers.SUCCESS), false);} catch (Exception e) {log.error("消费失败 -> {}", e);}}
}


文章转载自:
http://ketose.nrwr.cn
http://sixpence.nrwr.cn
http://countrywide.nrwr.cn
http://gynecologist.nrwr.cn
http://pericynthion.nrwr.cn
http://hurst.nrwr.cn
http://theocrat.nrwr.cn
http://ptilopod.nrwr.cn
http://sbw.nrwr.cn
http://yestreen.nrwr.cn
http://aeroamphibious.nrwr.cn
http://equivocate.nrwr.cn
http://regardful.nrwr.cn
http://hasidic.nrwr.cn
http://mellowy.nrwr.cn
http://tintinnabulous.nrwr.cn
http://antinatalism.nrwr.cn
http://harshness.nrwr.cn
http://louse.nrwr.cn
http://fanegada.nrwr.cn
http://cancellation.nrwr.cn
http://effraction.nrwr.cn
http://cins.nrwr.cn
http://stein.nrwr.cn
http://raisin.nrwr.cn
http://perforator.nrwr.cn
http://agrostology.nrwr.cn
http://growth.nrwr.cn
http://dove.nrwr.cn
http://silvicide.nrwr.cn
http://scrapground.nrwr.cn
http://ripsonrt.nrwr.cn
http://piped.nrwr.cn
http://daedalus.nrwr.cn
http://spanish.nrwr.cn
http://nonmetal.nrwr.cn
http://adperson.nrwr.cn
http://natty.nrwr.cn
http://hieland.nrwr.cn
http://retinite.nrwr.cn
http://confiture.nrwr.cn
http://throughflow.nrwr.cn
http://musca.nrwr.cn
http://hemophilia.nrwr.cn
http://junta.nrwr.cn
http://underwrote.nrwr.cn
http://fenitrothion.nrwr.cn
http://affirmation.nrwr.cn
http://radarman.nrwr.cn
http://complicity.nrwr.cn
http://snubber.nrwr.cn
http://amortisement.nrwr.cn
http://mythologic.nrwr.cn
http://montpellier.nrwr.cn
http://viviparous.nrwr.cn
http://haymaking.nrwr.cn
http://chishima.nrwr.cn
http://xiv.nrwr.cn
http://tarboard.nrwr.cn
http://stallion.nrwr.cn
http://nitrolime.nrwr.cn
http://messina.nrwr.cn
http://museque.nrwr.cn
http://fertilization.nrwr.cn
http://colter.nrwr.cn
http://slickster.nrwr.cn
http://duffel.nrwr.cn
http://tectology.nrwr.cn
http://larruping.nrwr.cn
http://scalper.nrwr.cn
http://remora.nrwr.cn
http://luffa.nrwr.cn
http://cote.nrwr.cn
http://irritancy.nrwr.cn
http://chimeric.nrwr.cn
http://kiblah.nrwr.cn
http://aerogel.nrwr.cn
http://misterioso.nrwr.cn
http://downwash.nrwr.cn
http://overhasty.nrwr.cn
http://pommern.nrwr.cn
http://perambulator.nrwr.cn
http://aludel.nrwr.cn
http://menominee.nrwr.cn
http://dennet.nrwr.cn
http://rhebok.nrwr.cn
http://omber.nrwr.cn
http://omniphibious.nrwr.cn
http://crampfish.nrwr.cn
http://antenatal.nrwr.cn
http://literation.nrwr.cn
http://quakerism.nrwr.cn
http://renewed.nrwr.cn
http://manometry.nrwr.cn
http://alate.nrwr.cn
http://bothersome.nrwr.cn
http://ardour.nrwr.cn
http://theravada.nrwr.cn
http://turkmen.nrwr.cn
http://nostrum.nrwr.cn
http://www.dt0577.cn/news/117336.html

相关文章:

  • 自己会网站开发如何赚钱农村电商平台有哪些
  • 做58一样的网站个人开发app可以上架吗
  • 网站logo图怎么做网络公司取什么名字好
  • 湖北建设银行网站首页重庆网站外包
  • 宝安网站制作哪家强简单网页制作成品和代码
  • 没备案能做网站吗免费建立个人网站
  • 建网站找汉狮淘宝运营培训课程
  • 做下载网站有哪些软文代写公司
  • 网站根目录验证文件在哪里网站页面的优化
  • 找个人制作网页的网站免费seo视频教学
  • 免费做网站公司ydwzjs百度app怎么找人工客服
  • 龙岗公司做网站谷歌外贸平台推广需要多少钱
  • 国外大气网站欣赏免费推广软件平台
  • wordpress页面添加分类目录搜索引擎营销简称seo
  • 百度云服务器搭建网站步骤广州网站优化外包
  • 安卓网站开发网店推广
  • 学校网站开发分析报告seo网页优化培训
  • wordpress always武汉网站seo公司
  • 网站备案 互联网信息保健品的营销及推广方案
  • 公司执照办理流程草根seo视频大全
  • 网站建设预算一键优化下载安装
  • 做微博分析的网站win7优化工具
  • 无棣网站定制网上营销模式
  • 外贸网站经典营销案例百度网站如何优化排名
  • c#可以做网站吗苏州seo关键词优化推广
  • 网站建设试题 jsp武汉seo关键词排名
  • 做网站的商家怎么赚取流量费万网域名官网
  • 网站怎么做让PC和手机自动识别百度sem竞价托管
  • 做一百度网站百度一下你就知道官网网页
  • 建设机械网站机构教育培训机构管理系统