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

电子商务网站建设规划实践成果网站推广建站

电子商务网站建设规划实践成果,网站推广建站,西安前端培训机构推荐,做旅行网站目录 一、定时器 二、标准库中的Timer 三、代码实现 四、死锁 一、定时器 代码中的定时器通常是在一定的时间执行对应的代码逻辑 二、标准库中的Timer public static void main(String[] args){Timer timer new Timer();timer.schedule(new TimerTask() {Overridepublic…

目录

一、定时器

二、标准库中的Timer

三、代码实现

四、死锁


一、定时器

代码中的定时器通常是在一定的时间执行对应的代码逻辑

二、标准库中的Timer

public static void main(String[] args){Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("时间到了后执行业务逻辑");}},1000);}

一个timer可以执行多个定时任务,后续添加任务继续调用schedule方法即可

三、代码实现

首先我们定义一个类用于描述任务

// 用于描述任务
class MyTimerTask {// 执行的任务private Runnable runnable;// 什么时间后执行(绝对的时间)private long time;/**** @param runnable 任务* @param time 多少时间后执行*/public MyTimerTask(Runnable runnable, long time) {this.runnable = runnable;this.time = System.currentTimeMillis() + time;}
}

然后我们开始定时器的编写,首先我们需要一个数据结构来存储提交的定时任务,这个数据结构需要能够依次取出最先执行的任务且要是线程安全的,首先想到的是优先级队列其次要有阻塞功能就是阻塞队列,然后我们需要定义一个提交任务的方法该方法中可以将提交的任务存入该队列中,然后在构造方法中创建一个扫描线程不断地取出该队列里地任务进行执行。在此之前我们使用优先级队列是存储定时任务的,那么我们可以先给上面的类实现Compareable接口重写compareTo方法

class MyTimer {// 1. 创建存储定时任务的数据结构BlockingQueue<MyTimerTask> queue = new PriorityBlockingQueue<>();// 2. 定义提交定时任务的方法public void schedule(Runnable runnable,long after) throws InterruptedException {MyTimerTask task = new MyTimerTask(runnable,after);queue.put(task);}// 3. 构造方法中定义扫描线程public MyTimer() {new Thread(()->{// 3.1 不断的取出数据看是否需要执行while (true) {try {// 3.1.1 拿出最先需要执行的任务判断是否到达执行时间MyTimerTask task = queue.take();if (System.currentTimeMillis() >= task.getTime()) {// 3.1.2 到达时间执行任务task.getRunnable().run();} else {// 3.1.3 没到时间重回队列queue.put(task);}} catch (InterruptedException e) {e.printStackTrace();}}}).start();}
}

这个时候盲等问题就出现了,比如我们提交了一个2小时后才执行的任务,但是按照上述代码则在这2小时的时间里不断地从队列中取出该任务比较后重回队列,那可以使用sleep(2h)这种方法来解决问题吗?答案是不能,使用sleep方法让线程挂起两个小时可以保证2小时后的任务会被执行,但是如果中途有其他更早的任务提交进来,那么这个任务就会错过执行的时间。那让每次sleep的时间短一点呢?答案同理也是不能的。我们可以使用wait方法来实现,wait(2h)然后在提交任务的方法中一但有新的任务提交调用notify唤醒wait即可,如果在这两个小时内没有任务提交,那么该方法还是会在2h后去执行任务。

 

// 2. 定义提交定时任务的方法public void schedule(Runnable runnable,long after) throws InterruptedException {MyTimerTask task = new MyTimerTask(runnable,after);queue.put(task);synchronized (this) {this.notify();}}// 3. 构造方法中定义扫描线程public MyTimer() {new Thread(()->{// 3.1 不断的取出数据看是否需要执行while (true) {try {// 3.1.1 拿出最先需要执行的任务判断是否到达执行时间MyTimerTask task = queue.take();if (System.currentTimeMillis() >= task.getTime()) {// 3.1.2 到达时间执行任务task.getRunnable().run();} else {// 3.1.3 没到时间重回队列queue.put(task);// 3.1.4 阻塞synchronized (this) {this.wait(task.getTime() - System.currentTimeMillis());}}} catch (InterruptedException e) {e.printStackTrace();}}}).start();}

这样我们就解决了盲等问题,但是还有一个原子性问题,就是如果此时扫描线程刚好取出了最先要执行的任务该任务是在2h后执行,扫描线程在判断是否到达执行时间之前,其他线程调用添加任务的方法加入了一个1h后需要执行的任务且方法执行完notify没有起到任何作用,此时扫描线程判断完后发现还没有到时间于是将任务入队后调用wait方法等待2h或被唤醒,刚好这2h没有其他任务加入,那么之前提交的1h后的任务就会延迟执行。这是由于扫描线程中操作不是原子性的我们需要调整锁的粒度

new Thread(()->{// 3.1 不断的取出数据看是否需要执行while (true) {try {synchronized (this) {// 3.1.1 拿出最先需要执行的任务判断是否到达执行时间MyTimerTask task = queue.take();if (System.currentTimeMillis() >= task.getTime()) {// 3.1.2 到达时间执行任务task.getRunnable().run();} else {// 3.1.3 没到时间重回队列queue.put(task);// 3.1.4 阻塞this.wait(task.getTime() - System.currentTimeMillis());}}} catch (InterruptedException e) {e.printStackTrace();}}}).start()

 那么notify代码中的锁粒度是否也需要调整呢?

四、死锁

如果我们将schedule方法中锁的粒度也扩大

public void schedule(Runnable runnable,long after) throws InterruptedException {synchronized (this) {MyTimerTask task = new MyTimerTask(runnable,after);queue.put(task);this.notify();}}

这个时候我们进行测试会发现什么也不会执行,发送了死锁。那这是为什么呢?

首先MyTimer实例被创建时扫描线程开始执行当他执行到此处时会因为阻塞队列中还没有元素而阻塞等待

但是锁还是被持有,此时提交任务的代码执行时发现需要先获取到锁,但是锁是被扫描线程持有,于是他需要阻塞等待,但是扫描线程中的take方法也需要执行了提交任务方法中的put才能继续执行,但是执行put方法有需要扫描线程先释放锁,所以发生死锁,这个时候我们需要将schedule方法中锁的粒度修改回去

http://www.qdjiajiao.com/news/7254.html

相关文章:

  • 网站设计点评百度一下你就知道网页
  • 个人写真拍摄东莞seo技术
  • 网站没排名要怎么做做网络优化的公司排名
  • 哪些网站是phpwind做的百度指数api
  • 市建设局领导名单萌新seo
  • 做经营性的网站需要注册什么nba湖人队最新消息
  • 无锡网站制作排名上海自动seo
  • 老薛主机做两个网站品牌营销推广策划方案
  • 驻马店市网站建设深圳网络推广哪家比较好
  • 网络推广方法有几种信息流优化师是什么
  • 广东省 政府网站 建设如何结合搜索检索与seo推广
  • 手机网站有什么好处独立站seo推广
  • 网站怎么更换域名成都纯手工seo
  • saas云建站抖音关键词搜索排名收费
  • 网站做镜像的有什么用百度推广代运营公司
  • 微信电商百度智能小程序怎么优化排名
  • 北京公司网站网络运营推广怎么做
  • 图书馆网站建设策划影响seo排名的因素有哪些
  • 成年做羞羞的视频网站space100个电商平台
  • 中国建设银行邀约提额网站网站首页关键词如何优化
  • 网站服务器错误提升排名
  • 视频弹幕网站怎么做的百度外推排名
  • 泰兴做网站的公司巨量引擎广告投放
  • 深圳营销型网站推广优化大师使用心得
  • 创意福州网站建设微博搜索引擎优化
  • 网站权限设计方案网站被禁用如何解决
  • 做网站需要掌握的技术谷歌广告投放教程
  • 公司网站建设 阿里营销图片大全
  • 自助建设网站app开发价格表
  • 外贸网站制作设计企业qq多少钱一年