精华内容
下载资源
问答
  • 我们在使用Android系统时,是不是会经常遇见卡机的问题,经常我是直接关机或者重新启动,然后就可以好了,但是也有更专业化的技术来android中延迟执行某个任务,那么我们就来讲讲这个延迟的问题。一、开启新线程1 ...

    我们在使用Android系统时,是不是会经常遇见卡机的问题,经常我是直接关机或者重新启动,然后就可以好了,但是也有更专业化的技术来android中延迟执行某个任务,那么我们就来讲讲这个延迟的问题。

    db8f500ea71dea3150fc5f2e5dd56e7d.png

    一、开启新线程

    1 newThread(newRunnable(){

    2 publicvoidrun(){

    3 Thread.sleep(XXXX);

    4 handler.sendMessage();----告诉主线程执行任务

    5 }

    6 }).start

    二、 利用定时器

    Java代码

    7 TimerTasktask=newTimerTask(){

    8 publicvoidrun(){

    9 //executethetask

    10 }

    11 };

    12 Timer timer = new Timer();timer.schedule(task, delay);

    Java代码

    13 newHandler().postDelayed(newRunnable(){

    14 publicvoidrun(){

    15 //executethetask

    16 }

    17 },delay);

    四、mHandler.sendEmptyMessageDelayed(WiFi_GPS_STATE_ON, 4 * 1000);

    五、利用AlarmManager,特点时刻广播指定意图 能实现,一般的简单任务不这么做

    上面我们讲了五个简单相处android中延迟执行某个任务的方法,使用代码解决的方法中都有一个共同点,那就是都是使用Java代码来实现。

    展开全文
  • java.util.concurrent.ScheduledThreadPoolExecutor 是JDK1 .6之后自带的包,功能强大,能实现定时器和延时加载的功能各类功能和处理方面优于Timer1、定时器:ScheduledThreadPoolExecutor 有个scheduleAtFixedRate...

    java.util.concurrent.ScheduledThreadPoolExecutor 是JDK1 .6之后自带的包,功能强大,能实现定时器和延时加载的功能

    各类功能和处理方面优于Timer

    1、定时器:

    ScheduledThreadPoolExecutor 有个scheduleAtFixedRate(command, initialDelay, period, unit) ;方法

    command: 执行的线程(可自己New一个)

    initialDelay:初始化执行的延时时间

    period: 时间间隔

    unit : 时间类型(如TimeUnit.SECONDS: 秒的方式执行,TimeUnit.DAYS : 天数的方式执行)

    具体代码:

    public static void main(String[] args) {

    stThread.scheduleAtFixedRate(new Runnable() {

    @Override

    public void run() {

    // TODO Auto-generated method stub

    System.out.println(new Date());

    }

    },

    20, 2, TimeUnit.SECONDS);

    }

    2、延时处理

    ScheduledThreadPoolExecutor 有个schedule(callable, delay, unit) ; 方法

    callable:回调方法

    delay:延时时间

    unit:时间类型,同定时器的unit一样

    具体代码:

    stThread.schedule((RolePrvlegeTask)SpringUtils.getBean("rolePrvlegeTask"), 1, TimeUnit.SECONDS);

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对聚米学院的支持。如果你想了解更多相关内容请查看下面相关链接

    展开全文
  • 1、利用延迟队列延时队列,第...延时1分钟再次执行等,下面先看看延时队列demo之后再看延时队列在项目中的使用:简单的延时队列要有三部分:第一实现了Delayed接口的消息体、第二消费消息的消费者、第三存放消息的延...

    1、利用延迟队列

    延时队列,第一他是个队列,所以具有对列功能第二就是延时,这就是延时对列,功能也就是将任务放在该延时对列中,只有到了延时时刻才能从该延时对列中获取任务否则获取不到……

    应用场景比较多,比如延时1分钟发短信,延时1分钟再次执行等,下面先看看延时队列demo之后再看延时队列在项目中的使用:

    简单的延时队列要有三部分:第一实现了Delayed接口的消息体、第二消费消息的消费者、第三存放消息的延时队列,那下面就来看看延时队列demo。

    一、消息体

    package com.delqueue;

    import java.util.concurrent.Delayed;

    import java.util.concurrent.TimeUnit;

    /**

    * 消息体定义 实现Delayed接口就是实现两个方法即compareTo 和 getDelay最重要的就是getDelay方法,这个方法用来判断是否到期…… */

    public class Message implements Delayed {

    private int id;

    private String body; // 消息内容

    private long excuteTime;// 延迟时长,这个是必须的属性因为要按照这个判断延时时长。

    public int getId() {

    return id;

    }

    public String getBody() {

    return body;

    }

    public long getExcuteTime() {

    return excuteTime;

    }

    public Message(int id, String body, long delayTime) {

    this.id = id;

    this.body = body;

    this.excuteTime = TimeUnit.NANOSECONDS.convert(delayTime, TimeUnit.MILLISECONDS) + System.nanoTime();

    }

    // 自定义实现比较方法返回 1 0 -1三个参数

    @Override

    public int compareTo(Delayed delayed) {

    Message msg = (Message) delayed;

    return Integer.valueOf(this.id) > Integer.valueOf(msg.id) ? 1

    : (Integer.valueOf(this.id) < Integer.valueOf(msg.id) ? -1 : 0);

    }

    // 延迟任务是否到时就是按照这个方法判断如果返回的是负数则说明到期否则还没到期

    @Override

    public long getDelay(TimeUnit unit) {

    return unit.convert(this.excuteTime - System.nanoTime(), TimeUnit.NANOSECONDS);

    }

    }

    二、消息消费者

    package com.delqueue;

    import java.util.concurrent.DelayQueue;

    public class Consumer implements Runnable {

    // 延时队列 ,消费者从其中获取消息进行消费

    private DelayQueue queue;

    public Consumer(DelayQueue queue) {

    this.queue = queue;

    }

    @Override

    public void run() {

    while (true) {

    try {

    Message take = queue.take();

    System.out.println("消费消息id:" + take.getId() + " 消息体:" + take.getBody());

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    }

    三、延时队列

    package com.delqueue;

    import java.util.concurrent.DelayQueue;

    import java.util.concurrent.ExecutorService;

    import java.util.concurrent.Executors;

    public class DelayQueueTest {

    public static void main(String[] args) {

    // 创建延时队列

    DelayQueue queue = new DelayQueue();

    // 添加延时消息,m1 延时3s

    Message m1 = new Message(1, "world", 3000);

    // 添加延时消息,m2 延时10s

    Message m2 = new Message(2, "hello", 10000);

    //将延时消息放到延时队列中

    queue.offer(m2);

    queue.offer(m1);

    // 启动消费线程 消费添加到延时队列中的消息,前提是任务到了延期时间

    ExecutorService exec = Executors.newFixedThreadPool(1);

    exec.execute(new Consumer(queue));

    exec.shutdown();

    }

    }

    将消息体放入延迟队列中,在启动消费者线程去消费延迟队列中的消息,如果延迟队列中的消息到了延迟时间则可以从中取出消息否则无法取出消息也就无法消费。

    这就是延迟队列demo,下面我们来说说在真实环境下的使用。

    使用场景描述:

    在打车软件中对订单进行派单的流程,当有订单的时候给该订单筛选司机,然后给当订单绑定司机,但是有时运气没那么好,订单进来后第一次没有筛选到合适的司机,但我们也不能就此结束派单,而是将该订单的信息放到延时队列中过个2秒钟在进行一次,其实这个2秒钟就是一个延迟,所以这里我们就可以使用延时队列来实现……

    下面看看简单的流程图:

    1da7a032ae64c087e28e26024a6ea09c.png

    下面来看看具体代码实现:

    在项目中有如下几个类:第一 、任务类 第二、按照任务类组装的消息体类 第三、延迟队列管理类

    任务类即执行筛选司机、绑单、push消息的任务类

    package com.test.delayqueue;

    /**

    * 具体执行相关业务的业务类

    * @author whd

    * @date 2017年9月25日 上午12:49:32

    */

    public class DelayOrderWorker implements Runnable {

    @Override

    public void run() {

    // TODO Auto-generated method stub

    //相关业务逻辑处理

    System.out.println(Thread.currentThread().getName()+" do something ……");

    }

    }

    消息体类,在延时队列中这个实现了Delayed接口的消息类是比不可少的,实现接口时有一个getDelay(TimeUnit unit)方法,这个方法就是判断是否到期的

    这里定义的是一个泛型类,所以可以将我们上面的任务类作为其中的task,这样就将任务类分装成了一个消息体

    package com.test.delayqueue;

    import java.util.concurrent.Delayed;

    import java.util.concurrent.TimeUnit;

    /**

    * 延时队列中的消息体将任务封装为消息体

    *

    * @author whd

    * @date 2017年9月25日 上午12:48:30

    * @param

    */

    public class DelayOrderTask implements Delayed {

    private final long time;

    private final T task; // 任务类,也就是之前定义的任务类

    /**

    * @param timeout

    * 超时时间(秒)

    * @param task

    * 任务

    */

    public DelayOrderTask(long timeout, T task) {

    this.time = System.nanoTime() + timeout;

    this.task = task;

    }

    @Override

    public int compareTo(Delayed o) {

    // TODO Auto-generated method stub

    DelayOrderTask other = (DelayOrderTask) o;

    long diff = time - other.time;

    if (diff > 0) {

    return 1;

    } else if (diff < 0) {

    return -1;

    } else {

    return 0;

    }

    }

    @Override

    public long getDelay(TimeUnit unit) {

    // TODO Auto-generated method stub

    return unit.convert(this.time - System.nanoTime(), TimeUnit.NANOSECONDS);

    }

    @Override

    public int hashCode() {

    return task.hashCode();

    }

    public T getTask() {

    return task;

    }

    }

    延时队列管理类,这个类主要就是将任务类封装成消息并并添加到延时队列中,以及轮询延时队列从中取出到时的消息体,在获取任务类放到线程池中执行任务

    package com.test.delayqueue;

    import java.util.Map;

    import java.util.concurrent.DelayQueue;

    import java.util.concurrent.ExecutorService;

    import java.util.concurrent.Executors;

    import java.util.concurrent.TimeUnit;

    import java.util.concurrent.atomic.AtomicLong;

    /**

    * 延时队列管理类,用来添加任务、执行任务

    *

    * @author whd

    * @date 2017年9月25日 上午12:44:59

    */

    public class DelayOrderQueueManager {

    private final static int DEFAULT_THREAD_NUM = 5;

    private static int thread_num = DEFAULT_THREAD_NUM;

    // 固定大小线程池

    private ExecutorService executor;

    // 守护线程

    private Thread daemonThread;

    // 延时队列

    private DelayQueue> delayQueue;

    private static final AtomicLong atomic = new AtomicLong(0);

    private final long n = 1;

    private static DelayOrderQueueManager instance = new DelayOrderQueueManager();

    private DelayOrderQueueManager() {

    executor = Executors.newFixedThreadPool(thread_num);

    delayQueue = new DelayQueue<>();

    init();

    }

    public static DelayOrderQueueManager getInstance() {

    return instance;

    }

    /**

    * 初始化

    */

    public void init() {

    daemonThread = new Thread(() -> {

    execute();

    });

    daemonThread.setName("DelayQueueMonitor");

    daemonThread.start();

    }

    private void execute() {

    while (true) {

    Map map = Thread.getAllStackTraces();

    System.out.println("当前存活线程数量:" + map.size());

    int taskNum = delayQueue.size();

    System.out.println("当前延时任务数量:" + taskNum);

    try {

    // 从延时队列中获取任务

    DelayOrderTask> delayOrderTask = delayQueue.take();

    if (delayOrderTask != null) {

    Runnable task = delayOrderTask.getTask();

    if (null == task) {

    continue;

    }

    // 提交到线程池执行task

    executor.execute(task);

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    /**

    * 添加任务

    *

    * @param task

    * @param time

    * 延时时间

    * @param unit

    * 时间单位

    */

    public void put(Runnable task, long time, TimeUnit unit) {

    // 获取延时时间

    long timeout = TimeUnit.NANOSECONDS.convert(time, unit);

    // 将任务封装成实现Delayed接口的消息体

    DelayOrderTask> delayOrder = new DelayOrderTask<>(timeout, task);

    // 将消息体放到延时队列中

    delayQueue.put(delayOrder);

    }

    /**

    * 删除任务

    *

    * @param task

    * @return

    */

    public boolean removeTask(DelayOrderTask task) {

    return delayQueue.remove(task);

    }

    }

    测试类

    package com.delqueue;

    import java.util.concurrent.TimeUnit;

    import com.test.delayqueue.DelayOrderQueueManager;

    import com.test.delayqueue.DelayOrderWorker;

    public class Test {

    public static void main(String[] args) {

    DelayOrderWorker work1 = new DelayOrderWorker();// 任务1

    DelayOrderWorker work2 = new DelayOrderWorker();// 任务2

    DelayOrderWorker work3 = new DelayOrderWorker();// 任务3

    // 延迟队列管理类,将任务转化消息体并将消息体放入延迟对列中等待执行

    DelayOrderQueueManager manager = DelayOrderQueueManager.getInstance();

    manager.put(work1, 3000, TimeUnit.MILLISECONDS);

    manager.put(work2, 6000, TimeUnit.MILLISECONDS);

    manager.put(work3, 9000, TimeUnit.MILLISECONDS);

    }

    }

    OK 这就是项目中的具体使用情况,当然具体内容被忽略,整体框架就是这样,还有这里使用java的延时队列但是这种方式是有问题的如果如果down机则会出现任务丢失,所以也可以考虑使用mq、redis来实现

    2、mq实现延迟消息

    在rabbitmq 3.5.7及以上的版本提供了一个插件(rabbitmq-delayed-message-exchange)来实现延迟队列功能。同时插件依赖Erlang/OPT 18.0及以上。

    插件源码地址:

    插件下载地址:

    安装:

    进入插件安装目录

    {rabbitmq-server}/plugins/(可以查看一下当前已存在的插件)

    下载插件

    rabbitmq_delayed_message_exchange

    wget https://bintray.com/rabbitmq/community-plugins/download_file?file_path=rabbitmq_delayed_message_exchange-0.0.1.ez

    (如果下载的文件名称不规则就手动重命名一下如:

    rabbitmq_delayed_message_exchange-0.0.1.ez)

    启用插件

    rabbitmq-plugins enable rabbitmq_delayed_message_exchange

    关闭插件

    rabbitmq-plugins disable rabbitmq_delayed_message_exchange

    插件使用

    通过声明一个x-delayed-message类型的exchange来使用delayed-messaging特性

    x-delayed-message是插件提供的类型,并不是rabbitmq本身的,发送消息的时候通过在header添加”x-delay”参数来控制消息的延时时间

    直接在maven工程的pom.xml文件中加入

    接下来在 application.properties 文件中加入redis配置:

    也很简单,代码如下:

    实现消息发送

    x-delay

    在这里我设置的延迟时间是3秒。

    消息消费者

    直接在main方法里运行Spring Boot程序,Spring Boot会自动解析 MessageReceiver 类的。

    接下来只需要用Junit运行一下发送消息的接口即可。

    运行完后,可以看到如下信息:

    消息发送时间:2018-05-03 12:44:53

    3秒钟后,Spring Boot控制台会输出:

    消息接收时间:2018-05-03 12:44:56

    接收到的消息:hello i am delay msg

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    展开全文
  • 作者: 一字马胡转载标志 【2017-11-03】更新日志日期更新内容备注2017-11-03添加转载标志持续更新如果在一个ScheduleExecutorService中提交一个任务,这个任务的调度周期设置的时间比任务本身执行的时间短的话会...

    作者: 一字马胡

    转载标志 【2017-11-03】

    更新日志

    日期

    更新内容

    备注

    2017-11-03

    添加转载标志

    持续更新

    如果在一个ScheduleExecutorService中提交一个任务,这个任务的调度周期设置

    的时间比任务本身执行的时间短的话会出现什么情况?也就是在线程调度时间已经到了

    但是上次的任务还没有做完的情况下,ScheduleExecutorService是怎么处理的?

    这个问题曾经困扰了我很久,我们都知道,ScheduleExecutorService是一个支持周期调度的线程池,我们可以设置调度的周期period,ScheduleExecutorService会按照设定好的周期调度我们的任务,如果我们设定的调度周期小于任务运行时间,那么很好理解,比如说我们设置的调度周期为1秒,而任务实际只需要10毫秒就可以执行完成一次,那么执行完成之后放到调度队列即可,下次调度时间到了再次调度执行。那么,如果我们的任务执行时间大于我们设定的调度时间会怎么样?比如我们设定的调度周期为1秒,但是我们的任务每次需要执行2秒,这个情况是不是很奇怪呢?

    对于ScheduleExecutorService来说,你给我设定的调度周期是1秒,那么我当然1秒就会去运行一次你,但是运行1秒后发现你还在运行,那我是再次运行你还是等你运行完成再调度你运行?

    当然,这都是我的主观臆断来猜测ScheduleExecutorService的原理,ScheduleExecutorService的真正原理需要去阅读源码来理解,下面带着这个问题,以解决这个问题为目标去看一下ScheduleExecutorService的源码吧。

    首先,我们使用下面的代码作为测试:

    private static Runnable blockRunner = () -> {

    try {

    TimeUnit.SECONDS.sleep(2);

    System.out.println("one round:" + new Date());

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    };

    private static ScheduledExecutorService scheduledExecutorService =

    Executors.newScheduledThreadPool(2);

    public static void main(String ... args) {

    scheduledExecutorService

    .scheduleAtFixedRate(blockRunner, 0, 100, TimeUnit.MILLISECONDS);

    }

    我们设定了调度周期为100毫秒,但是blockRunner实际上需要执行2秒才能返回。关于java的线程池,已经在前面的文章中写到了,可以参考下面的文章:

    先来看一下scheduleAtFixedRate这个方法:

    public ScheduledFuture> scheduleAtFixedRate(Runnable command,

    long initialDelay,

    long period,

    TimeUnit unit) {

    if (command == null || unit == null)

    throw new NullPointerException();

    if (period <= 0)

    throw new IllegalArgumentException();

    ScheduledFutureTask sft =

    new ScheduledFutureTask(command,

    null,

    triggerTime(initialDelay, unit),

    unit.toNanos(period));

    RunnableScheduledFuture t = decorateTask(command, sft);

    sft.outerTask = t;

    delayedExecute(t);

    return t;

    }

    我们的任务command被包装了两次,一次变成了一个ScheduledFutureTask类型的对象,然后又变成了RunnableScheduledFuture类型的对象。然后执行了一个方法delayedExecute,这个方法字面意思上看起来像是延时执行的意思,看一下它的代码:

    private void delayedExecute(RunnableScheduledFuture> task) {

    if (isShutdown())

    reject(task);

    else {

    super.getQueue().add(task);

    if (isShutdown() &&

    !canRunInCurrentRunState(task.isPeriodic()) &&

    remove(task))

    task.cancel(false);

    else

    ensurePrestart();

    }

    }

    它的执行逻辑是:如果线程池被关闭了,那么拒绝提交的任务,否则,将该任务添加队列中去。这个队列就是ThreadPoolExecutor中的workQueue,而这个workQueue是在ThreadPoolExecutor的构造函数中被初始化的,也就是下面这关键的一句:

    public ScheduledThreadPoolExecutor(int corePoolSize,

    ThreadFactory threadFactory,

    RejectedExecutionHandler handler) {

    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,

    new DelayedWorkQueue(), threadFactory, handler);

    }

    也就是说,我们的任务被添加到了一个DelayedWorkQueue队列中去了,而DelayedWorkQueue我们在Java阻塞队列详解中已经分析过,它是一个可以延迟消费的阻塞队列。而延时的时间是通过接口Delayed的getDelay方法来获得的,我们最后找到ScheduledFutureTask实现了Delayed的getDelay方法。

    public long getDelay(TimeUnit unit) {

    return unit.convert(time - now(), NANOSECONDS);

    }

    time变量是什么?原来是delay,好像和period无关啊!!分析了这么久,发现这是第一次执行任务的逻辑啊,我想知道的是第二次、第三次以后和初始的delay无关之后的周期调度的情况啊,继续找吧!

    然后发现了ScheduledFutureTask的run方法,很明显这就是任务调度被执行的关键所在,看下代码:

    public void run() {

    boolean periodic = isPeriodic();

    if (!canRunInCurrentRunState(periodic))

    cancel(false);

    else if (!periodic)

    ScheduledFutureTask.super.run();

    else if (ScheduledFutureTask.super.runAndReset()) {

    setNextRunTime();

    reExecutePeriodic(outerTask);

    }

    }

    }

    最为关键的地方在于:

    else if (ScheduledFutureTask.super.runAndReset()) {

    setNextRunTime();

    reExecutePeriodic(outerTask);

    }

    首先是:runAndReset()这个方法,然后是setNextRunTime()这个方法,然后是reExecutePeriodic(outerTask)这个方法。

    第一个方法runAndReset()貌似是执行我们的提交的任务的,我们看下代码:

    protected boolean runAndReset() {

    if (state != NEW ||

    !UNSAFE.compareAndSwapObject(this, runnerOffset,

    null, Thread.currentThread()))

    return false;

    boolean ran = false;

    int s = state;

    try {

    Callable c = callable;

    if (c != null && s == NEW) {

    try {

    c.call(); // don't set result

    ran = true;

    } catch (Throwable ex) {

    setException(ex);

    }

    }

    } finally {

    // runner must be non-null until state is settled to

    // prevent concurrent calls to run()

    runner = null;

    // state must be re-read after nulling runner to prevent

    // leaked interrupts

    s = state;

    if (s >= INTERRUPTING)

    handlePossibleCancellationInterrupt(s);

    }

    return ran && s == NEW;

    }

    关键的地方是c.call()这一句,这个c就是我们提交的任务。

    第二个方法setNextRunTime()的意思是设置下次执行的时间,下面是他的代码细节:

    private void setNextRunTime() {

    long p = period;

    if (p > 0)

    time += p;

    else

    time = triggerTime(-p);

    }

    我们只需要看p>0这个分支就可以了,其实这是两种策略。我们的示例对应了第一个分支的策略,所以很显然,time这个变量会被加p,而p则是我们设定好的period。下面我们找一下这个time是在哪里初始化的,回忆一下scheduleAtFixedRate这个方法的内,我们说我们的任务被包装了两次,而time就是在这里被初始化的:

    /**

    * Returns the trigger time of a delayed action.

    */

    private long triggerTime(long delay, TimeUnit unit) {

    return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));

    }

    /**

    * Returns the trigger time of a delayed action.

    */

    long triggerTime(long delay) {

    return now() +

    ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));

    }

    无论如何,我们知道一个任务会被运行完一次之后再次设置时间,然后线程池会获取任务来执行,而任务队列是一个延时阻塞队列,所以也就造成了周期性运行的假象。可以看下下面获取任务的take方法:

    public RunnableScheduledFuture> take() throws InterruptedException {

    final ReentrantLock lock = this.lock;

    lock.lockInterruptibly();

    try {

    for (;;) {

    RunnableScheduledFuture> first = queue[0];

    if (first == null)

    available.await();

    else {

    long delay = first.getDelay(NANOSECONDS);

    if (delay <= 0)

    return finishPoll(first);

    first = null; // don't retain ref while waiting

    if (leader != null)

    available.await();

    else {

    Thread thisThread = Thread.currentThread();

    leader = thisThread;

    try {

    available.awaitNanos(delay);

    } finally {

    if (leader == thisThread)

    leader = null;

    }

    }

    }

    }

    } finally {

    if (leader == null && queue[0] != null)

    available.signal();

    lock.unlock();

    }

    }

    可以看到,如果delay小于等于0,那么就是说需要被立即调度,否则延时delay这样一段时间。也就是延时消费。

    结论就是,一个任务会被重复添加到一个延时任务队列,所以同一时间任务队列中会有多个任务待调度,线程池会首先获取优先级高的任务执行。如果我们的任务运行时间大于设置的调度时间,那么效果就是任务运行多长时间,调度时间就会变为多久,因为添加到任务队列的任务的延时时间每次都是负数,所以会被立刻执行。

    8c4c160ebdf7

    扫码入群

    展开全文
  • android/java 中两种延时执行的方法

    千次阅读 2016-05-03 16:55:23
    // 消息处理方式实现延时  new Handler().postDelayed(new Runnable()  {  public void run()  {  myDialog.dismiss();  }  },3000);    // 线
  • (1)适合多个相同程序代码的线程去处理同一资源的情况;(2)可以避免由于Java的单继承特性所带来的的局限;(3)增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。二、线程的状态要想实现多线程,必须...
  • 最近在研究系统滴答定时器,简单的说一下对于STM32单片机中,有关于系统...原因是由于最近在一个项目中,沿用老方法,使用原子库自带的延时处理程序中,需要的一些延时。目前使用来看,好像是影响不大,没有什么危...
  • Java如何实现任务超时处理不才黄某 码农沉思录任务超时处理是比较常见的需求,比如在进行一些比较耗时的操作(如网络请求)或者在占用一些比较宝贵的资源(如数据库连接)时,我们通常需要给这些操作设置一个超时时间,...
  • 新书购买传送门=》当当网本章将介绍下列内容:创建线程执行器创建固定大小的线程执行器在执行器中执行任务并返回结果运行多个任务并处理第一个结果运行多个任务并处理所有结果在执行器中延时执行任务在执行器中周期...
  • Java中对超时任务的处理有两种方式:一种是基于异步任务结果的超时获取,一种则是使用延时任务来终止超时操作。下文将详细说明。一、基于异步任务结果的超时获取基于异步任务结果的获取通常是跟线...
  • Java中对超时任务的处理有两种方式:一种是基于异步任务结果的超时获取,一种则是使用延时任务来终止超时操作。下文将详细说明。一、基于异步任务结果的超时获取基于异步任务结果的获取通常是跟线...
  • Java如何实现任务超时处理

    千次阅读 2019-03-25 20:55:54
    Java中对超时任务的处理有两种方式:一种是基于异步任务结果的超时获取,一种则是使用延时任务来终止超时操作。下文将详细说明。 、基于异步任务结果的超时获取 基于异步任务结果的获取通常...
  • 1、利用延迟队列延时队列,第...延时1分钟再次执行等,下面先看看延时队列demo之后再看延时队列在项目中的使用:简单的延时队列要有三部分:第一实现了Delayed接口的消息体、第二消费消息的消费者、第三存放消息的延...
  • Java中对超时任务的处理有两种方式:一种是基于异步任务结果的超时获取,一种则是使用延时任务来终止超时操作。下文将详细说明。一、基于异步任务结果的超时获取基于异步任务结果的获取通常是跟线...
  • 应用场景比较多,比如延时1分钟发短信,延时1分钟再次执行等,下面先看看延时队列demo之后再看延时队列在项目中的使用: 简单的延时队列要有三部分:第一实现了Delayed接口的消息体、第二消费消息的消费者、第...
  • 感谢人民邮电大学授权并发网发布此书样章,新书购买传送门=》当当网 ...在执行器中延时执行任务 在执行器中周期性执行任务 在执行器中取消任务 在执行器中控制任务的完成 在执行器中分离任务的启动与结果的处理 处...
  • 定义setTimeout()和setInterval()经常被用来处理延时和定时任务。setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式,而setInterval()则可以在每隔指定的毫秒数循环调用函数或表达式,直到clearInterval把...
  • 延时任务解决方案

    2020-08-18 15:54:14
    延时任务是指把需要延迟执行的任务叫做延迟任务。如红包 24 小时未被查收,需要延迟执退还业务;每个月账单日,需要给用户发送当月的对账单;订单下单之后30分钟未支付,系统自动取消订单。本文以订单下单超时支付为...
  • 在使用各种 listener 时,稍有不注意就会导致内存泄露,因此在使用延时返回的回调时,需要格外小心。demo先看一个的 demo:MainActivity 点击按钮后,调用 LongTimeOperation 开启一个耗时 10 秒的线程,并在执行...
  • 第二种:延时多久执行,就是当发生一件事情后,根据这件时间发生的时间定时多久后执行任务,如:15分钟后关闭订单付款状态,24小时候后关闭订单并且释放库存,而由于第二种一般都是单一数据的处理(主要是指数据量...
  • java线程池详解

    2019-02-12 11:11:45
    1. 创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率 例如: 记创建线程消耗时间T1,执行任务消耗时间T2,... 比如:延时执行、定时循环执行的策略等 运用线程池都能进行很好的实现
  • 第二种:延时多久执行,就是当发生一件事情后,根据这件时间发生的时间定时多久后执行任务,如:15分钟后关闭订单付款状态,24小时候后关闭订单并且释放库存,而由于第二种一般都是单一数据的处理(主要是指数据量...
  • 一、线程池线程池适合处理的任务:执行时间短、工作内容较为单一。合理使用线程池带来的好处:1)降低资源消耗:重复利用已创建的线程降低线程创建和销毁造成的开销2)提高响应速度:当任务到达时,任务可以不用等待...
  • 第二种:延时多久执行,就是当发生一件事情后,根据这件时间发生的时间定时多久后执行任务,如:15分钟后关闭订单付款状态,24小时候后关闭订单并且释放库存,而由于第二种一般都是单一数据的处理(主要是指数据量...
  • 互联网 Java 工程师进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识。 2 leetcode 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》...
  • 第二种:延时多久执行,就是当发生一件事情后,根据这件时间发生的时间定时多久后执行任务,如:15分钟后关闭订单付款状态,24小时候后关闭订单并且释放库存,而由于第二种一般都是单一数据的处理(主要是指数据量...
  • 概念:(1)什么是防抖:多次事件触发后、事件处理函数只执行一次,并且是在触发操作结束时执行。(2)原理:延时操作处理函数、若设定的延时到来之前、再次触发函数、则清除上一次的延时操作定时器、重新定时3.使用:...

空空如也

空空如也

1 2 3 4
收藏数 80
精华内容 32
关键字:

java延时处理执行

java 订阅