栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java多线程~认识并手动实现一个定时器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java多线程~认识并手动实现一个定时器

目录

定时器

标准库中的定时器

定时器的使用

实现一个定时器

定时器的构成

核心接口schedule

mailBox对象 

 扫描器worker线程

完整代码

代码测试 


定时器

定时器是软件开发中的一个重要组件,类似于一个闹钟,达到一个特定时间后,就执行某个指定好的代码。

标准库中的定时器

· 标准库提供了一个Timer类,Timer类的核心方法为schedule.

· schedule方法包含两个参数,第一个参数指定将要执行的任务代码,第二个参数指定多长时间后执行这段代码(单位为毫秒).

定时器的使用
import java.util.Timer;
import java.util.TimerTask;

public class TimerTest {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Hello");
            }
        },3000);
    }
}

上述代码的意思为TimerTask对象为所要执行的任务代码,指定为输出"Hello",后面的3000为指定的时间,即程序运行3000毫秒后执行这段代码 .

运行结果

实现一个定时器

定时器的构成

· 一个带优先级的阻塞队列

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

· 队列中的每一个元素是一个Task对象

· Task中带有一个时间属性,队首元素就是即将执行的元素

· 同时有一个work线程一直扫描队首元素,看队首元素是否需要执行

核心接口schedule

Timer类提供的核心接口就是schedule接口,用于注册一个任务,并指定这个任务多长时间后执行

    public void schedule(Runnable command, long after) {
        Task task = new Task(command,after);
        queue.offer(task);
        synchronized(mailBox) {
            mailBox.notify();
        }
    }

mailBox对象 

mailBox对象是定时器中非常重要的一个成员,可以借助该对象的wait和notify来解决while(true)的忙等问题,具体应用在下方扫描器woker中

    //避免worker线程出现忙等的情况
    private Object mailBox = new Object();

 扫描器worker线程

woker线程的作用是扫描队首元素,看其是否能够执行这个任务,如果不利用mailBox对象的wait方法,woker线程就会一直扫描阻塞队列队首位置,一秒钟扫描几万次,但在加上mailBox对象的wait方法后就可以解决这个忙等的问题了

public class MyTimer {

    class Worker extends Thread {
        @Override
        public void run() {
            while(true) {
                try {
                    Task task = queue.take();
                    long curTime = System.currentTimeMillis();
                    if(task.time > curTime) {
                        //如果执行时间还未到,就将任务重新放入阻塞队列中
                        queue.put(task);
                        synchronized (mailBox) {
                            //指定等待时间
                            mailBox.wait(task.time - curTime);
                        }
                    }else {
                        //时间如果到了就执行任务
                        task.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public MyTimer() {
        //启动work线程
        Worker worker = new Worker();
        worker.start();
    }
}

完整代码
import java.util.concurrent.PriorityBlockingQueue;


public class MyTimer {
    static class Task implements Comparable {
        private Runnable command;
        private long time;
        public Task(Runnable command, long time) {
            this.command = command;
            //time中存的是绝对时间,超过这个时间任务就需要被执行
            this.time = System.currentTimeMillis() + time;
        }

        public void run() {
            command.run();
        }

        @Override
        public int compareTo(Task o) {
            //谁的时间小谁排在前面
            return (int)(time - o.time);
        }
    }

    //核心结构: 一个带优先级的阻塞队列
    private PriorityBlockingQueue queue = new PriorityBlockingQueue<>();
    //避免worker线程出现忙等的情况
    private Object mailBox = new Object();

    class Worker extends Thread {
        @Override
        public void run() {
            while(true) {
                try {
                    Task task = queue.take();
                    long curTime = System.currentTimeMillis();
                    if(task.time > curTime) {
                        //如果执行时间还未到,就将任务重新放入阻塞队列中
                        queue.put(task);
                        synchronized (mailBox) {
                            //指定等待时间
                            mailBox.wait(task.time - curTime);
                        }
                    }else {
                        //时间如果到了就执行任务
                        task.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public MyTimer() {
        //启动work线程
        Worker worker = new Worker();
        worker.start();
    }
    //schedule
    public void schedule(Runnable command, long after) {
        Task task = new Task(command,after);
        queue.offer(task);
        synchronized(mailBox) {
            mailBox.notify();
        }
    }
}

代码测试 
class MyTimerTest {
    public static void main(String[] args) {
        MyTimer timer = new MyTimer();
        Runnable command = new Runnable() {
            @Override
            public void run() {
                System.out.println("我来了");
                timer.schedule(this,3000);
            }
        };
        timer.schedule(command,3000);
    }
}

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/933488.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号