1.  Java中sleep和wait的区别

① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。

sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。

② 锁: 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。

Thread.sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。

③ 使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。

synchronized(x){  
      x.notify() 
     //或者wait() 
   }

2.可能在面试的时候面试官会问你java实现多线程的方式有哪些,你可能会知道java要提供继承Thread类和实现runnable接口这两种方式来实现线程,但是如果问为什么这样设计呢?

首先说一下,我们知道java的集成只能是单继承,不能多集成,这样的话就会有缺陷,比如想增加一个功能的时候必须要去修改基类。而实现runnable接口的这种方式可以很好的解决java不能多继承导致的缺陷。这是第一个原因。

再说第二个,我们知道实现runnable接口的方式代码的写法是这样的:new Thread(new runnable(){ public void run(){    ....}})。在这种情况下我们可以看到其实整个的runnable对象中的代码可以被多个Thread对象实例所使用共享,这样就可以解决一个多个线程处理同一资源的情况。做到了线程安全。在这里我觉着有必要通过一个代码的方式来解释一下第二个优点是如何实现的。

3.首先来说一下Timer是怎么工作的,Timer 是按照一定的时间段或者一个时间点根据定时的定时任务进行执行的。

Timer这个java提供的定时器有如下的特点:

① 他是一个单线程的,也就是你启动一个Timer定时器就是启动了一个线程。

② Timer定时器默认的情况下不是守护线程,但是可以通过构造参数设置为守护线程,守护线程在没有其他线程的情况下自己会挂掉。

③ 使用Timer定时器的时候 要跟一个TimerTask定时任务结合来使用。而且TimerTask其实底层就是一个队列,在TimerTask中增加的任务会在定时器这个线程里面挨个的执行。TimerTask也有自己的cannel取消等方法。

④ TimerTask中的run方法无法抛出,所以要进行try catch捕获,如果其中任何一个任务发生异常没有被捕获,则其他任务也将被终止。

我们看到TImer定时器这个类有两个schedule方法。其中都有的就是一个TimerTask这个任务。我对这两个方法进行了一个总结:

方法详解:
(1)schedule(TimerTask task, Date executeTime)
当executeTime<=currentTime时,task任务会在currentTimer立即执行
当executeTime>currentTime时,task会在未来的executeTime执行
 
(2)schedule(TimerTask task, Date firstTime, long period)
当firstTime <=currentTime时,task任务会在currentTimer立即执行,
当firstTime >currentTime时,task会在未来的executeTime执行,
执行任务所用的时间taskUsedTime<peroid,则下一个任务执行的时间是上次任务执行完成的时间+peroid,任务按时间间隔peroid周期性执行任务
执行任务所用的时间taskUsedTime>peroid,则下一个任务执行的时间是上次任务执行完成的时间+taskUsedTime,任务按时间间隔taskUsedTime 周期性执行任务
 
 
(3)schedule(TimerTask task, long delay)
任务延迟delay毫秒进行执行
 
(4)schedule(TimerTask task, long delay, long period)
A、延迟delay毫秒第一次执行,
B、执行任务所用的时间taskUsedTime<peroid,则下一个任务执行的时间是上次任务执行完成的时间+peroid, 任务按时间间隔peroid周期性执行任务
C、执行任务所用的时间taskUsedTime>peroid,则下一个任务执行的时间是上次任务执行完成的时间+taskUsedTime, 任务按时间间隔taskUsedTime 周期性执行任务
 
(5)scheduleAtFixedRate(TimerTask task, long delay, long period)
 
(6)scheduleAtFixedRate(TimerTask task, Date firstTime,  long period)
         startTime = currentTime
A、当firstTime>currentTime,任务则在currentTime执行
B、当firstTime<currentTime,任务会发生追赶执行,追赶执行的次数expectCount=(currentTime-firstTime)/peroid+1;
  第一个peroid属于追赶阶段,如果追赶上则等待执行startTime+peroid时间任务,如果没有追赶上则直接执行startTime+peroid时间的任务
 
 首先我们看一下Timer这个类的构造函数,因为我们知道我们再使用Timer这个类的时候我们只是创建了一个Timer对象,并没有像Thread那样主动的去调用start方法。所以我想答应也应该明白我们定时器的启动是在构造函数中做的,没错,从源码中我们可以得道验证:

Timer是一个单独的线程,从第152行我们就可以看到,我们可以设置线程的名称,可以设置是否是守护线程,然后调用start方法定时器就起作用了。但是并不会立即执行。线程调用start后也不会立即执行,这在上一篇中已经有说到了,他其实是把当前的线程示例放到了一个线程组中等待被执行。

哪我们就看他是如何调度的也就是schdule是如何执行的呢。

这里我们补充一下,queue是一个TaskQueue

多线程中sleep和wait的区别,以及多线程的实现方式及原因,定时器--Timer的更多相关文章

  1. 转 Java多线程中Sleep与Wait的区别

    Java中的多线程是一种抢占式的机制,而不是分时机制.抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行. 共同点: 1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数, ...

  2. Java学习从菜鸟变大鸟之三 多线程中Thread 和Runnable的区别与运用

    多线程机制是java中的一个特点,掌握它对后面的知识的理解至关重要,是java工程师的必备知识,多线程指在单个程序中可以运行多个不同的线程执行的不同的任务,线程是一个程序内部的顺序控制流.进程是静态的 ...

  3. Java多线程中start()和run()的区别

    Java的线程是通过java.lang.Thread类来实现的.VM启动时会有一个由主方法所定义的线程.可以通过创建Thread的实例来创建新的线程.每个线程都是通过某个特定Thread对象所对应的方 ...

  4. java多线程中 volatile与synchronized的区别-阿里面试

    volatile 与 synchronized 的比较(阿里面试官问的问题) ①volatile轻量级,只能修饰变量.synchronized重量级,还可修饰方法 ②volatile只能保证数据的可见 ...

  5. 多线程中sleep和wait的区别

    前几天去UC笔试,有一道简答题问到了.之前还真一直没留意到这个问题,所以答得也不好. 无论学习什么都好,通过对比学习更有利于发现事物的共性和个性,对于知识点的理解更有明显效果(这也可能是UC笔试题上, ...

  6. Java多线程中Sleep与Wait的区别

    Java中的多线程是一种抢占式的机制 而不是分时机制.抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行. 共同点: 1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数 ...

  7. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  8. 认识多线程中start和run方法的区别?

    一.认识多线程中的 start() 和 run() 1.start(): 先来看看Java API中对于该方法的介绍: 使该线程开始执行:Java 虚拟机调用该线程的 run 方法. 结果是两个线程并 ...

  9. iOS多线程中,队列和执行的排列组合结果分析

    本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到 ...

随机推荐

  1. Linux命令之乐--seq

    用法及参数:  -f, --format=格式      使用printf 样式的浮点格式,默认是g%  -s, --separator=字符串     使用指定字符串分隔数字(默认使用:\n)  - ...

  2. selenium + chrome 被检测,反反爬小记

    selenium + chrome 很多难以采集的网站都使用selenium爬取,但是后来发现selenium有特征值,会被检测出来,今天来小结一下反反爬方案 测试网站 全绿好像代表没被检测出 中间人 ...

  3. angular 路由

    在路由时传递数据 1. 在查询参数中传递数据 /product?id=1&name=2 => ActivatedRoute.queryParams[id] 2.在路由路径中传递数据 {p ...

  4. navicat自动生成DDL语句

    场景:当我们在开发库修改表结构之后,需要把这些表结构的变化同步更新到生产库,这时候可以在Navicat中copy表结构变更的SQL语句. 当你点击了“设计表”进行修改表结构,在保存表结构之前点击“SQ ...

  5. 160524、Linux下如何启动、关闭Oracle以及打开关闭监听

    1. linux下启动oraclesu - oraclesqlplus /nologconn /as sysdbastartupexitlsnrctl startexit2. linux下关闭orac ...

  6. Spring的AOP细节理解

    什么是AOP?AOP:是面向切面编程,是对面向对象编程(oop)的一种补充,为什么需要AOP?例如在我们做一个计算器,要求我们每次运行对应的功能(也就是进行运算时)都要输出日志,以便于知道程序是怎么运 ...

  7. 使用Ansible自动配置JDK环境

    1.首先安装好Ansible环境,具体步骤请见Ansible安装 2.先创建hosts文件(为后面编写脚本安装JDK做铺垫) [root@localhost /]# vi hosts [jdktest ...

  8. C# ArcEngine 实现点击要素高亮并弹出其属性

    本文是模仿ArcMap里面的Identify(识别)功能,通过点击要素,使其高亮显示并弹出其属性表!本文只做了点击查询! 本文所用的环境为VS2010,AecEngine基于C#语言,界面是用Dev做 ...

  9. Fat URLs Client Identification

    w在每个URL后面都附加一个用户特有的标识码. HTTP The Definitive Guide Some web sites keep track of user identity by gene ...

  10. VS调用python方法

    1.  安装python3.7 2.  Vs2010中配置python: 3.添加头文件:#include <Python.h> 4.问题:error LNK2001: 无法解析的外部符号 ...