多线程——定时器

目录

定义

标准库中的定时器

 定时器的实现


定义:

类似于一个闹钟,达到设定的时间之后,就会执行某个指定的代码

标准库中的定时器:

标准库提供了Timer类,Timer类的核心方法为schedule(即将执行的代码,多长时间后执行)

mport java.util.Timer;
import java.util.TimerTask;

public class demo19 {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask()//本质就是runnable {
            @Override
            public void run() {
                System.out.println("hello");
            }
        },2000);//表示2s后执行run
        System.out.println("world");
    }
}

执行结果:

 定时器的实现

1.带优先级的阻塞队列(因为阻塞队列中的任务都有各自的执行时刻 (delay). 最先执行的任务一定是 delay 最小的. 使用带 优先级的队列就可以高效的把这个 delay 最小的任务找出来.)

2.队列中的每个元素是一个task对象

3.task中带有一个时间属性

4.有一个worker线程一直扫描队首元素,看队首元素是否需要执行

Task 类用于描述一个任务,因为要实现带优先级的队列,所以要实现comparable接口

    class Task implements Comparable<Task>{
    public Runnable runnable;
    public long time;
    public Task(Runnable runnable,long delay){
        this.runnable=runnable;
        //取当前时刻的时间戳++delay表示该任务实际执行的时间戳
        this.time=System.currentTimeMillis()+delay;
    }
    @Override
    public int compareTo(Task o) {
        return (int)(this.time-o.time);//取出最小时间的元素
    }

完整代码

package work;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.PriorityBlockingQueue;

public class demo19 {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        }, 2000);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello2");
            }
        }, 2000);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello3");
            }
        }, 2000);
    }
}


class Task implements Comparable<Task> {
    public Runnable runnable;
    public long time;

    public Task(Runnable runnable, long delay) {
        this.runnable = runnable;
        //取当前时刻的时间戳++delay表示该任务实际执行的时间戳
        this.time = System.currentTimeMillis() + delay;
    }

    @Override
    public int compareTo(Task o) {
        return (int) (this.time - o.time);//取出最小时间的元素
    }
}


class MyTimer {
    //带优先级的阻塞队列
    private PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<>();
    //创建一个锁对象
    private Object locker = new Object();

    //注册一个任务, 并指定这个任务多长时间后执行.
    public void schedule(Runnable runnable, long delay) {
        Task mytask = new Task(runnable, delay);
        //构造Task,插入队列
        queue.put(mytask);
        locker.notify();
    }

    //构造线程
    public MyTimer() {
        Thread t = new Thread(() -> {
            while (true) {
                synchronized (locker) {
                    try {
                        //阻塞出队列
                        Task task = queue.take();
                        long curTime = System.currentTimeMillis();
                        if (task.time <= curTime) {
                            //时间到了,开始执行任务
                            task.runnable.run();
                        } else {
                            //阻塞入队列,把刚刚取出的任务放回队列中
                            queue.put(task);
                            locker.wait(task.time-curTime);
                            //取出队首元素,发现还没到时间就wait,但是有了新任务,就唤醒wait
                            //执行新任务,不像sleep那样死等
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t.start();
    }
}

执行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发呆的百香果子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值