Java线程阻塞方法sleep()与wait()的全面讲解

一、前期基础知识储备

sleep()和wait()方法都是Java中造成线程阻塞的方法。感兴趣的读者可以参见笔者之前的文章《Java中什么方法导致线程阻塞》,里面详细讲述了为什么Java要造成线程阻塞和Java中造成线程阻塞的几种方法。

(1)线程的生命周期

这是笔者在谷歌图片中找到的一张简单描述线程生命周期的图片,可以看到,一个线程正常的生命周期中会经历“创建”“就绪”“运行”“阻塞”“运行”“死亡”等几个生命周期,其中“阻塞”是我们开发者非常需要关注的,因为通过Java提供的阻塞方法,可以做到资源和线程最合理的调配,而其中sleep()和wait()方法就是Java中实现线程阻塞的关键性方法。

(2)sleep()和wait()方法的阻塞线程的场景

我们这里,来看第二张图片,这张图片就比较详细的向我们展现了一个线程的完整生命周期中发生的各种“事件”和调用的各种方法。

我们来总结一下sleep()和wait()方法的阻塞场景。

①sleep()实现线程阻塞的方法,我们称之为“线程睡眠”,方式是超时等待,怎么理解?就是sleep()通过传入“睡眠时间”作为方法的参数,时间一到就从“睡眠”中“醒来”;

②wait()方法实现线程阻塞的方法,我们称之为“线程等待”,方式有两种:

1)和sleep()方法一样,通过传入“睡眠时间”作为参数,时间到了就“醒了”;

2)不传入时间,进行一次“无限期的等待”,只用通过notify()方法来“唤醒”。

二、sleep()和wait()的区别

通过上面两幅图的展示和笔者的相关描述,相信读者你已经有几分清楚了,sleep()和wait()方法的区别之一,就是实现线程阻塞的方式不一样。

那么sleep()和wait()二者还有一个很大的区别就是,二者“是否释放同步锁”不一样。我们都知道,多线程开发中,为了实现不同线程间的同步会采用同步锁的方式——synchronized即在线程使用一个资源时为其加锁,这样其他的线程便不能访问那个资源了,直到解锁后才可以访问。

感兴趣的读者可以参考笔者之前文章《利用synchronized实现线程同步》里面详细介绍了多线程开发中利用synchronized实现线程同步的方式。

而使用sleep()和wait()两种方法对于“CPU执行权”和“同步锁”的方式不同:

①sleep()释放CPU执行权,但不释放同步锁;

②wait()释放CPU执行权,也释放同步锁,使得其他线程可以使用同步控制块或者方法。

以上,就是sleep()和wait()方法的两个关键性区别。

总结:综上我们利用下表展示sleep()和wait()的所有区别:

ps:谢谢博友的更正。这里进行改正: wait()为Object基类中的方法,调用时亦需要捕获异常,以下为wait()可能抛出的异常:

PS:能用图说明的问题,我们就用图来说明,能用表说明的问题,我们就用表来说明,这样理解起来非常清晰。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • Java线程中sleep和wait的区别详细介绍

    Java中的多线程是一种抢占式的机制,而不是分时机制.抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行. 共同点: 1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回. 2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException. 如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法.如果此刻线程B正在wait/sleep/

  • Java Thread之Sleep()使用方法总结

    一.API简介 Thread.sleep()是Thread类的一个静态方法,使当前线程休眠,进入阻塞状态(暂停执行),如果线程在睡眠状态被中断,将会抛出IterruptedException中断异常..主要方法如下: [a]sleep(long millis)  线程睡眠 millis 毫秒 [b]sleep(long millis, int nanos)  线程睡眠 millis 毫秒 + nanos 纳秒 Api文档: 二.使用方法 注意:在哪个线程里面调用sleep()方法就阻塞哪个线程.

  • JAVA线程sleep()和wait()详解及实例

    JAVA线程sleep()和wait()详解及实例 sleep 1.sleep是Thread的一个静态(static)方法.使得Runnable实现的线程也可以使用sleep方法.而且避免了线程之前相互调用sleep()方法,引发死锁. 2.sleep()执行时需要赋予一个沉睡时间.在沉睡期间(阻塞线程期间),CPU会放弃这个线程,执行其他任务.当沉睡时间到了之后,该线程会自动苏醒,不过此时线程不会立刻被执行,而是要等CPU分配资源,和其他线程进行竞争. 3.此外如果这个线程之前获取了一个机锁,

  • Java线程阻塞方法sleep()与wait()的全面讲解

    一.前期基础知识储备 sleep()和wait()方法都是Java中造成线程阻塞的方法.感兴趣的读者可以参见笔者之前的文章<Java中什么方法导致线程阻塞>,里面详细讲述了为什么Java要造成线程阻塞和Java中造成线程阻塞的几种方法. (1)线程的生命周期 这是笔者在谷歌图片中找到的一张简单描述线程生命周期的图片,可以看到,一个线程正常的生命周期中会经历"创建""就绪""运行""阻塞""运行"

  • java 线程之对象的同步和异步(实例讲解)

    一.多线程环境下的同步与异步 同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求不到,怎么办,A线程只能等待下去. package com.jalja.org.thread.demo01; public class Thread02 { public synchronized void method1(){ System.out.println("method1:"+Thread.currentThread().getName()); try { T

  • 正确结束Java线程的方法

    使用标志位 很简单地设置一个标志位,名称就叫做isCancelled.启动线程后,定期检查这个标志位.如果isCancelled=true,那么线程就马上结束. public class MyThread implements Runnable{ private volatile boolean isCancelled; public void run(){ while(!isCancelled){ //do something } } public void cancel(){ isCance

  • 浅谈java线程join方法使用方法

    本博客简介介绍一下java线程的join方法,join方法是实现线程同步,可以将原本并行执行的多线程方法变成串行执行的 如图所示代码,是并行执行的 public class ThreadTest { //private static final Long count = 10000L; public static void main(String[] args){ long base = System.currentTimeMillis(); try { ThreadJoin t1 = new

  • java线程阻塞中断与LockSupport使用介绍

    上周五和周末,工作忙里偷闲,在看java cocurrent中也顺便再温故了一下Thread.interrupt和java 5之后的LockSupport的实现. 在介绍之前,先抛几个问题. Thread.interrupt()方法和InterruptedException异常的关系?是由interrupt触发产生了InterruptedException异常? Thread.interrupt()会中断线程什么状态的工作? RUNNING or BLOCKING? 一般Thread编程需要关注

  • Java线程生命周期的终止与复位

    目录 Thread生命周期 生命周期概述 线程生命周期流程图 线程生命周期测试 启动线程 java中的启动 Hotspot中的启动 线程中断与复位 不要使用stop方法 使用interrupt方法 线程的复位 其他的线程复位 Thread生命周期 生命周期概述 Java的线程状态描述放在Thread类里面的枚举类State中.总共包含了6中状态(从出生到死亡). public enum State { /** * 尚未启动的线程的线程状态 (没有start) */ NEW, /** * 可运行线

  • Java使用阻塞队列控制线程通信的方法实例详解

    本文实例讲述了Java使用阻塞队列控制线程通信的方法.分享给大家供大家参考,具体如下: 一 点睛 阻塞队列主要用在生产者/消费者的场景,下面这幅图展示了一个线程生产.一个线程消费的场景: 负责生产的线程不断的制造新对象并插入到阻塞队列中,直到达到这个队列的上限值.队列达到上限值之后生产线程将会被阻塞,直到消费的线程对这个队列进行消费.同理,负责消费的线程不断的从队列中消费对象,直到这个队列为空,当队列为空时,消费线程将会被阻塞,除非队列中有新的对象被插入. BlockingQueue的核心方法:

  • 聊聊Java中是什么方法导致的线程阻塞

    一.为什么引入线程阻塞机制? 为了解决对共享存储区的访问冲突,Java 引入了同步机制,现在让我们来考察多个线程对共享资源的访问,显然同步机制已经不够了,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个.为了解决这种情况下的访问控制问题,Java 引入了对阻塞机制的支持. 阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),学过操作系统的同学对它一定已经很熟悉了.Java 提供了大量方法来支持阻塞,下面让我们逐一分析. 二.Java中实

  • 详解Java编程中线程同步以及定时启动线程的方法

    使用wait()与notify()实现线程间协作 1. wait()与notify()/notifyAll() 调用sleep()和yield()的时候锁并没有被释放,而调用wait()将释放锁.这样另一个任务(线程)可以获得当前对象的锁,从而进入它的synchronized方法中.可以通过notify()/notifyAll(),或者时间到期,从wait()中恢复执行. 只能在同步控制方法或同步块中调用wait().notify()和notifyAll().如果在非同步的方法里调用这些方法,在

  • Java线程池的几种实现方法及常见问题解答

    工作中,经常会涉及到线程.比如有些任务,经常会交与线程去异步执行.抑或服务端程序为每个请求单独建立一个线程处理任务.线程之外的,比如我们用的数据库连接.这些创建销毁或者打开关闭的操作,非常影响系统性能.所以,"池"的用处就凸显出来了. 1. 为什么要使用线程池 在3.6.1节介绍的实现方式中,对每个客户都分配一个新的工作线程.当工作线程与客户通信结束,这个线程就被销毁.这种实现方式有以下不足之处: •服务器创建和销毁工作的开销( 包括所花费的时间和系统资源 )很大.这一项不用解释,可以

随机推荐