定时器与单例模式

本次更新的主要内容是多线程中的定时器Timer和单例模式,本来打算分两次更新的,这次就在一起更新了。这次更新完之后,多线程的基础理论知识系列就完结了,后续会发布Mysql的内部技术分析,多线程实战等内容,也会不定时的在每一期穿插更新一个算法或者编程技巧。

主要内容如下:

1 、定时器

在JDK中,Timer类主要负责计划任务的功能,也就是在执行定的时间开始执行某一个任务,Timer类的主要任务是设置计划任务,但封装任务的类却是TimerTask类(抽象类)。

1.1、方法schedule(TimerTask task,Date time)

该方法的作用是在指定的日期执行一次某一个任务。

样例如下:

public class MyTask extends TimerTask {

@Override

public void run() {

//执行代码

}

}

MyTask task = new MyTask();

Timer timer = new Timer();

timer.schedule(task,new Date());

timer线程启动后,会一直存在,并没有结束,不能设置为守护线程,会影响task的执行。

执行时间晚于当前时间。 到时间自动执行。

执行时间早于当前时间。 立即执行

Timer中有多个TimerTask任务及任务延时。 TimerTask是以队列的方式一个一个被顺序地执行,所以执行时间有可能和预期不一样,因为前面的任务有可能消耗过大,后面的任务的运行时间也被延后。被延后的任务,会在前一个任务结束后立即执行。

1.2、方法schedule(TimerTask task,Date first,long period)

该方法的作用是在指定的日期之后按指定的时间间隔,无线循环地执行某一任务。

执行时间晚于当前时间。 到时间自动执行。

执行时间早于当前时间。 立即执行

执行任务时间被延时。 任务的消耗时间大于period值,任务被无间隔的循环执行。

TimerTask类的cancel()方法。 该方法的作用是将自身从任务队列中进行删除。其他任务不受影响。

Timer类的cancel方法。 该方法的作用是将任务队列中的全部任务进行清除。且进程被摧毁。该方法并不一定总是生效的,失败的原因是没有争抢到queue锁。

1.3、方法schedule(TimerTask task,long delay)

该方法是以当前时间为参考,再次基础上延迟一定的毫秒数后执行一次TimerTask任务。

1.4、方法schedule(TimerTask task,long delay,long period)

该方法是以当前时间为参考,在此时间基础上,延迟指定的毫秒数,再以某一时间间隔无限次的执行某一任务。

1.5、方法scheduleAtFixedRate(TimerTask task,Date firstTime,long period)

方法schedule和scheduleAtFixedRate都会按顺序执行,所以不要考虑非线程安全的情况。主要区别在于有没有追赶性。

scheduleAtFixedRate方法具有追赶性,执行任务时间晚于计划时间,被卡掉的时间的任务,也会被执行。而schedule方法不会。

2、单例模式

2.1、饿汉模式

饿汉模式,在调用方法前,实例已经被创建了。

public class MyObject {

//立即加载方式

private static MyObject myObject = new MyObject();

private MyObject(){

}

public static MyObject getInstance() {

//立即加载

//缺点不能有其他实例

//get方法没有同步

return myObject;

}

}

2.2、懒汉模式

懒汉模式,在调用方法时才被创建。

public class MyObject {

//立即加载方式

private static MyObject myObject;

private MyObject(){

}

public static MyObject getInstance() {

if(myObject != null){

}else {

myObject = new MyObject();

}

return myObject;

}

}

该代码在多线程环境中,会出现多个实例的情况,非安全。

解决办法:

声明关键字synchronized,但执行效率非常低下。

public class MyObject {

//立即加载方式

private static MyObject myObject;

private MyObject(){

}

synchronized public static MyObject getInstance() {

try{

if(myObject != null){

}else {

myObject = new MyObject();

}

}catch(Exception e ){

e.printStackTrace();

}

return myObject;

}

}

同步代码块,同上。

使用DCL双检查机制。成功解决。

public class MyObject {

//立即加载方式

private volatile static MyObject myObject;

private MyObject(){

}

public static MyObject getInstance() {

try{

if(myObject != null){

}else {

synchronized(MyObject.class){

if(myObject == null){

myObject = new MyObject();

}

}

}

}catch(Exception e ){

e.printStackTrace();

}

return myObject;

}

}

2.3、静态内部类

public class MyObject {

//内部类

private static class MyObjectHandler {

private static MyObject myObject = new MyObject();

}

private MyObject(){}

public static MyObject getInstance() {

return MyObjectHandler.myObject;

}

}

2.4、序列化问题

静态内部类可以达到线程安全,但是不能解决序列化时多个实例的问题。

public class MyObject {

//内部类

private static class MyObjectHandler {

private static MyObject myObject = new MyObject();

}

private MyObject(){}

public static MyObject getInstance() {

return MyObjectHandler.myObject;

}

protected Object readResolve() throws ObjectStreamException {

return MyObjectHandler.myObject;

}

}

2.5、静态代码块

原理:静态代码块在使用类是已经执行了。

public class MyObject {

private static MyObject instance = null;

private MyObject(){}

static {

instance = new MyObject();

}

public static MyObject getInstance(){

return instance;

}

}

2.6、枚举类实现

原理:和静态代码块类似,在使用枚举类时,构造方法会自动调用。职责单一原则,应该隐藏枚举类。

public class MyObject {

public enum MyEnumSingleton {

connectionFactory;

private Connection connection;

private MyEnumSingleton() {

try{

....

}catch(){

}

}

public Connection getConnection(){

return connection;

}

}

public static Connection getConnection() {

return MyEnumSingleton.connectionFactory.getConnection();

}

}

java多线程机制计时器_java多线程定时器与单例模式相关推荐

  1. java线程怎么用_Java多线程基本使用

    一.概念 1.进程 1.1进程:是一个正在进行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元. 1.2线程:就是进程中一个独立的控制单元,线程在控制着进程的执行,一 ...

  2. java线程代码实现_Java 多线程代码实现讲解

    作为一个完全面向对象的语言,Java提供了类 java.lang.Thread 来方便多线程编程,这个类提供了大量的方法来方便我们控制自己的各个线程.那么如何提供给 Java 我们要线程执行的代码呢? ...

  3. java 锁旗标_Java多线程

    Java多线程 1. 多线程存在的意义 多线程最大的作用就是能够创建"灵活响应"的桌面程序,而编写多线程最大的困难就是不同线程之间共享资源的问题,要使这些资源不会同时被多个线程访问 ...

  4. java反射机制知识_Java反射机制讲解,程序员必须掌握的知识点

    关注程序员7歌,一起用技术改变世界 大家好,我是程序员7歌,今天我为大家讲解Java的反射机制. 首先我们来看看反射的概念: Java反射说的就是在程序运行中,任何一个类,我们都可以知道这个类的方法和 ...

  5. java 反射机制性能_Java反射机制的用途和缺点

    Java反射机制的用途和缺点 反射的用途 Uses of Reflection Reflection is commonly used by programs which require the ab ...

  6. java 计时器_Java多线程并发容器之并发倒计时器

    从火箭发场景来学习Java多线程并发闭锁对象 倒计时器场景 在我们开发过程中,有时候会使用到倒计时计数器.最简单的是:int size = 5; 执行后,size-这种方式来实现.但是在多线程并发的情 ...

  7. java同步与死锁_Java多线程 - 线程同步与死锁

    一.线程同步 1)模拟多个用户同时从银行账户里面取钱 ● Account 类:银行账户类,里面有一些账户的基本信息,以及操作账户信息的方法 //模拟银行账户 classAccount {private ...

  8. java进程与线程_Java多线程笔记(零):进程、线程与通用概念

    前言 不积跬步,无以至千里:不积小流,无以成江海.在学习Java多线程相关的知识前,我们首先需要去了解一点操作系统的进程.线程以及相关的基础概念. 进程 通常,我们把一个程序的执行称为一个进程.反过来 ...

  9. java 多线程间通讯_JAVA多线程间通讯常用实现方法解析

    如何实现线程间通讯,有如下三种方法: 1.使用Semaphore (信号量)类来控制线程的等待和释放 功能:三个线程 a .b .c 并发运行,b,c 需要 a 线程的数据怎么实现 分析:考虑到多线程 ...

最新文章

  1. git用.gitignore忽略指定文件
  2. position:fixed和scroll实现div浮动【示例】
  3. 按位异或运算和求反运算解析
  4. python学习:map()
  5. 气象数据领航无人飞行器线路优化大赛解决方案(3rd place)
  6. C语言 break 和 continue - C语言零基础入门教程
  7. Zepto自定义模块打包构建
  8. 科学和工程中的信号处理
  9. QT5.14.2+VS2019安装配置教程Windows
  10. 【语音处理】时域信号分析基本工具,什么是窗函数
  11. ubuntu16.04 360随身WiFi2
  12. 不应忘却的纪念-小百合(Lilybbs)
  13. 杭州公司java开发工程师常见面试问题
  14. 【STL编程】【竞赛常用】【part 2】
  15. 3个技术男搞恋爱版 ChatGPT,估值70亿...
  16. VUE前端二级部门联动下拉菜单
  17. cadence SPB17.4 - 取消(删除)扇出
  18. 本人对2023年网络安全演练规划要求
  19. 【I2C】i2c-tools的使用方法
  20. git创建分支并推送到远程分支

热门文章

  1. 还在维护吗_你的模具生锈了吗?来了解一下这些防锈维护事项
  2. python爬取2019年计算机就业_2019年最新Python爬取腾讯招聘网信息代码解析
  3. python全栈计划_Python 全栈学习视频教程,包含了从 0-99天的全栈学习计划,估计可以学习 1024 小时。...
  4. php 监控文件夹变化,swoole 开发中监听目录文件变化, 自动重启项目
  5. SSM-网站后台管理系统制作(3)---Google的reCaptcha验证码
  6. struts2 过滤器和拦截器的区别和使用
  7. bzoj千题计划287:bzoj1228: [SDOI2009]ED
  8. 编译:ffmpeg,精简ffmpeg.exe
  9. 【学习笔记】Xcode常见设置
  10. Python 调试 PDB