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

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

简介

在Java多线程编程中,线程状态的控制是非常重要的一个部分。线程可以处于多种状态,例如就绪状态,运行状态,阻塞状态等等。本篇文章主要讲解Java线程阻塞方法sleep()与wait()的使用和区别。

sleep()方法

sleep()方法是Thread类中一个静态方法。sleep()方法的作用是使当前线程暂停执行一段时间,然后再继续执行。sleep()方法接受一个参数,表示休眠的时间的毫秒数。这个参数可以是long类型的,也可以是int类型的。

try {
    Thread.sleep(1000); // 暂停1秒
} catch (InterruptedException e) {
    e.printStackTrace();
}

在上面的示例中,当线程执行到sleep()方法时,这个线程就会进入睡眠状态,并且暂停执行1秒钟。在1秒钟之后,这个线程会醒来,继续往下执行。

需要注意的是,在调用sleep()方法时,需要处理InterruptedException异常。如果在休眠过程中,调用Thread.interrupt()方法中断了这个线程,那么sleep()方法就会抛出这个异常。

wait()方法

wait()方法是Object类中的一个方法。wait()方法的作用是使当前线程进入等待状态,等待其他线程通过notify()或notifyAll()方法唤醒它。wait()方法可以接受一个参数,表示等待的时间的毫秒数,也可以不传参数。

synchronized (lock) {
    try {
        lock.wait(); // 等待其他线程唤醒
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

在上面的示例中,synchronized锁住了一个对象lock,然后在这个对象上调用了wait()方法。这个线程就会进入等待状态,并且释放锁。等待其他线程调用lock.notify()方法唤醒它。

需要注意的是,在调用wait()方法时,需要先获取synchronized锁,即wait()方法必须在synchronized块中调用,否则会抛出IllegalMonitorStateException异常。

区别

  • wait()方法必须在synchronized块中调用,而sleep()方法不需要。
  • wait()方法会释放锁,而sleep()方法不会释放锁。
  • wait()方法只有在被其他线程调用notify()或notifyAll()方法时才会继续执行,而sleep()方法会在规定的时间后自动醒来继续执行。

示例

示例一:使用sleep()方法

public class SleepDemo {

    public static void main(String[] args) {
        Runnable task = () -> {
            for (int i = 0; i < 10; i++) {
                System.out.println("线程" + Thread.currentThread().getName() + "执行第" + i + "次任务");
                try {
                    Thread.sleep(1000); // 暂停1秒钟
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        new Thread(task, "A").start();
        new Thread(task, "B").start();
    }
}

在上面的示例中,创建了两个线程并行执行,每个线程都会执行10次任务,每次任务之间暂停1秒钟。虽然两个线程中的任务不是完全同步的,但是它们是交替执行的。

示例二:使用wait()方法

public class WaitDemo {
    private static final Object lock = new Object();

    public static void main(String[] args) {
        Runnable task1 = () -> {
            synchronized (lock) {
                System.out.println(Thread.currentThread().getName() + "开始执行");
                try {
                    lock.wait(); // 等待唤醒,释放锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "继续执行");
            }
        };

        Runnable task2 = () -> {
            synchronized (lock) {
                System.out.println(Thread.currentThread().getName() + "开始执行");
                lock.notify(); // 唤醒等待线程
                System.out.println(Thread.currentThread().getName() + "唤醒线程");
            }
        };

        new Thread(task1, "A").start();
        new Thread(task2, "B").start();
    }
}

在上面的示例中,创建了两个线程并行执行,线程A会先获得锁并进入等待状态,线程B会在执行过程中唤醒线程A。唤醒线程A会释放锁,线程B会获得锁并继续执行。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java线程阻塞方法sleep()与wait()的全面讲解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • JSP response对象实现文件下载的两种方式

    我会为您详细讲解“JSP response对象实现文件下载的两种方式”的完整攻略。 下载文件是Web开发中非常常见的功能之一。在JSP中,我们可以使用response对象来实现文件下载的功能。具体来说,实现文件下载可以采用两种方式: 1. 使用response的OutputStream方式 使用response的OutputStream方式的基本流程如下: …

    Java 2023年6月15日
    00
  • 利用SpringDataJPA开启审计功能,自动保存操作人操作时间

    利用SpringDataJPA开启审计功能可以方便地对每次数据操作进行记录,包括操作人、操作时间等信息。这样做有利于数据追溯和安全性控制。下面是实现该功能的步骤: 添加必要的依赖 在项目的pom.xml文件中添加以下依赖: <dependency> <groupId>org.springframework.boot</group…

    Java 2023年5月20日
    00
  • Java面向对象的封装你了解吗

    Java的面向对象编程中,封装是指将功能和数据进行封装,使得外部无法直接访问、修改。封装有助于保护数据的安全性,同时也提高了代码的可维护性和可扩展性。 封装的实现主要是通过访问修饰符来控制属性和方法的访问权限。Java 中常用的访问修饰符包括 public、private、protected 和 default。其中,public 表示公开的,任何地方都可以…

    Java 2023年5月26日
    00
  • Java顺序查找算法详解

    Java顺序查找算法详解 什么是顺序查找? 顺序查找,也称线性查找,是一种简单但效率低下的搜索算法,其基本思想是从数据结构的起点开始,顺序扫描整个数据结构,逐个比较查找的值与数据结构中的值,直到找到目标值位置或查找完所有元素为止。 顺序查找算法实现 在Java中,我们可以使用以下的代码实现顺序查找算法: public static int linearSea…

    Java 2023年5月19日
    00
  • java 日期各种格式之间的相互转换实例代码

    下面是 “Java 日期各种格式之间的相互转换实例代码” 的完整攻略: 基本介绍 在Java中,可以使用java.text.SimpleDateFormat类来格式化日期,具体的格式定义可以参考Java官方文档中的SimpleDateFormat类说明(notes)。在这个过程中,需要注意日期格式的大小写,具体规则请参考文档说明。 日期转换 以下是实现日期转…

    Java 2023年5月20日
    00
  • Java BigDecimal基础用法详解

    Java BigDecimal基础用法详解 什么是BigDecimal Java中的float和double类型是不能精确表示十进制数的,这对于很多需要精确计算的场景是不适用的。而BigDecimal是Java提供的一个可以精确表示任意大小和精度的十进制数类。 常用构造方法 BigDecimal(double val):通过一个Double类型的值来构造Bi…

    Java 2023年5月26日
    00
  • springboot2启动时执行,初始化(或定时任务)servletContext问题

    在Spring Boot 2中,我们可以使用ApplicationRunner和CommandLineRunner接口来在应用程序启动时执行初始化操作或定时任务。此外,我们还可以使用ServletContextInitializer接口来在应用程序启动时执行Servlet上下文初始化操作。 ApplicationRunner和CommandLineRunne…

    Java 2023年5月15日
    00
  • Java 字符串拼接竟然有这么多姿势(收藏版)

    当我们在Java中进行字符串拼接时,有多种方式可以完成,每种方式都有其独特的优点和适用场景。以下是其中一些常用的方式: 1. “+”符号拼接字符串 使用“+”符号,可以很方便地进行字符串拼接。在代码中简单地使用“+”将字符串连接起来即可。例如: String s1 = "Hello "; String s2 = "world!&…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部