首页 > 编程语言 >[Java并发]

[Java并发]

时间:2024-07-14 22:29:28浏览次数:8  
标签:Java Thread join 并发 线程 sleep 方法 wait

sleep()、wait()、join()、yield()

yield

在Java中,yield() 是一个Thread类的方法,它用于暂停当前线程并允许其他线程运行。它是一种线程调度的建议,告诉调度器可以切换到其他就绪状态的线程。调用yield()方法后,线程会从运行状态转换为就绪状态,让其他线程有机会执行。

下面是一个简单的Java代码示例,展示了yield()方法的用法:

public class YieldExample implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
            // 调用 yield() 方法
            Thread.yield();
        }
    }

    public static void main(String[] args) {
        // 创建两个线程
        Thread thread1 = new Thread(new YieldExample(), "Thread 1");
        Thread thread2 = new Thread(new YieldExample(), "Thread 2");

        // 启动线程
        thread1.start();
        thread2.start();
    }
}

在上面的示例中,我们创建了两个线程并启动它们。每个线程都会打印从0到4的数字。在每次循环中,我们调用了yield()方法,这样两个线程就可以交替执行,让出CPU时间给其他线程。

请注意,yield()方法的调用并不能保证当前线程一定会让出CPU时间,它只是一个建议。实际执行结果取决于操作系统和线程调度器的具体实现。

join

在Java中,join() 是Thread类的一个方法,用于等待调用该方法的线程执行完毕。当一个线程调用另一个线程的 join() 方法时,调用线程将被阻塞,直到被调用的线程执行完毕。

join() 方法有以下两种常见的用法:

  1. 使用 join() 方法等待单个线程完成:
Thread thread = new Thread(new MyRunnable());
thread.start();

// 在主线程中调用 join() 方法等待 thread 线程执行完毕
try {
    thread.join();
} catch (InterruptedException e) {
    e.printStackTrace();
}

System.out.println("thread 执行完毕");

在上面的示例中,我们创建了一个新线程并启动它。在主线程中,我们调用了join()方法等待新线程执行完毕。主线程会被阻塞,直到新线程执行完毕后才会继续执行。

  1. 使用 join() 方法等待多个线程完成:
Thread thread1 = new Thread(new MyRunnable());
Thread thread2 = new Thread(new MyRunnable());

thread1.start();
thread2.start();

// 在主线程中分别调用 join() 方法等待 thread1 和 thread2 线程执行完毕
try {
    thread1.join();
    thread2.join();
} catch (InterruptedException e) {
    e.printStackTrace();
}

System.out.println("thread1 和 thread2 执行完毕");

在上面的示例中,我们创建了两个新线程,并启动它们。然后在主线程中分别调用两个线程的 join() 方法,以等待它们执行完毕。主线程会被阻塞,直到两个线程都执行完毕后才会继续执行。

需要注意的是,join() 方法可能会抛出 InterruptedException,因此在使用时需要处理异常。这是由于线程在等待期间可能被中断,导致 join() 方法提前返回。

使用 join() 方法可以实现线程之间的协作和同步,确保某个线程在其他线程执行完毕后再继续执行。

sleep

在Java中,sleep() 是Thread类的一个静态方法,用于暂停当前线程的执行一段指定的时间。它是一种线程睡眠的机制。

sleep() 方法有以下两种常见的用法:

  1. 使用 sleep() 方法暂停当前线程的执行:
try {
    // 暂停当前线程执行 500 毫秒(0.5 秒)
    Thread.sleep(500);
} catch (InterruptedException e) {
    e.printStackTrace();
}

System.out.println("线程睡眠后继续执行");

在上面的示例中,我们使用 sleep() 方法暂停当前线程的执行。在这个例子中,当前线程将会睡眠500毫秒(0.5秒),然后继续执行后续的代码。

需要注意的是,sleep() 方法可能会抛出 InterruptedException,因此在使用时需要处理异常。这是由于线程在睡眠期间可能被中断,导致 sleep() 方法提前返回。

  1. 使用 sleep() 方法实现定时任务:
class MyTask implements Runnable {
    public void run() {
        try {
            // 定时任务,每隔 1 秒执行一次
            while (true) {
                System.out.println("执行定时任务");
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

// 创建一个新线程执行定时任务
Thread thread = new Thread(new MyTask());
thread.start();

在上面的示例中,我们创建了一个新线程来执行定时任务。在定时任务的循环中,我们使用 sleep() 方法使线程睡眠1秒,然后再执行下一次循环。这样就可以实现定时任务的效果。

需要注意的是,sleep() 方法会暂停当前线程的执行,但不会释放锁。如果在同步代码块或同步方法中调用 sleep() 方法,其他线程仍然无法获取到该锁。因此,在使用 sleep() 方法时要注意对锁的使用,避免可能的线程竞争和死锁问题。

总结:
sleep() 方法用于暂停当前线程的执行一段指定的时间。它可以用于实现线程的延时执行、定时任务等场景。然而,需要注意处理可能抛出的 InterruptedException 异常,并避免在同步代码块或同步方法中使用 sleep() 方法导致的线程竞争和死锁问题。

wait

在Java中,wait() 是Object类的一个方法,用于使当前线程进入等待状态,直到其他线程调用相同对象上的 notify()notifyAll() 方法来唤醒等待线程。

wait() 方法有以下常见的用法:

  1. 在同步代码块中使用 wait() 方法:
synchronized (sharedObject) {
    try {
        // 当前线程进入等待状态,释放对象的锁
        sharedObject.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    // 当线程被唤醒后,继续执行
    System.out.println("线程被唤醒");
}

在上面的示例中,我们在一个同步代码块中调用了 wait() 方法。当线程执行到 wait() 方法时,它会释放对象的锁并进入等待状态,直到其他线程调用相同对象上的 notify()notifyAll() 方法来唤醒等待线程。

需要注意的是,在调用 wait() 方法前必须获得对象的锁,因此通常在同步代码块或同步方法中使用 wait() 方法。

  1. 使用 wait() 方法实现线程间的协作:
class MyTask implements Runnable {
    private final Object lock;

    public MyTask(Object lock) {
        this.lock = lock;
    }

    public void run() {
        synchronized (lock) {
            try {
                System.out.println("线程开始执行任务");

                // 执行任务的一部分

                // 等待其他线程完成特定条件
                lock.wait();

                // 线程被唤醒后继续执行任务的剩余部分
                System.out.println("线程继续执行任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 创建一个共享的锁对象
Object lock = new Object();

// 创建一个新线程执行任务
Thread thread = new Thread(new MyTask(lock));
thread.start();

// 在适当的时机唤醒等待的线程
synchronized (lock) {
    lock.notify();
}

在上面的示例中,我们创建了一个共享的锁对象,并在一个新线程的任务中使用 wait() 方法进行等待。主线程在适当的时机调用 notify() 方法来唤醒等待的线程。

需要注意的是,wait() 方法必须在同步块中使用,并且在调用 wait() 方法前必须获得对象的锁,否则会抛出 IllegalMonitorStateException 异常。

总结:
wait() 方法用于使当前线程进入等待状态,直到其他线程调用相同对象上的 notify()notifyAll() 方法来唤醒等待线程。它常用于线程间的协作和同步。需要在同步块中使用 wait() 方法,并在调用 wait() 方法前获得对象的锁。同时,需要注意处理可能抛出的 InterruptedException 异常和使用适当的唤醒机制。

标签:Java,Thread,join,并发,线程,sleep,方法,wait
From: https://www.cnblogs.com/DCFV/p/18302145

相关文章

  • Java实现堆排序算法详解及优化
    引言堆排序(HeapSort)是一种基于堆数据结构的比较排序算法。它具有良好的时间复杂度特性,在许多实际应用中表现出色。本文将详细讲解如何使用Java实现堆排序算法,并结合图解和实例代码,帮助您全面理解这一高级排序算法。同时,我们还将探讨堆排序的优化方法,以进一步提高其性能。......
  • Java基础05:类型转换
    由于Java是强类型语言,所以要进行有些运算的时候的,需要用到类型转换。整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。转换从低级到高级(根据容量来看)。低------------------------------------------>高byte,short,char—>i......
  • 学Java的第二周(结构)
    条件结构1.顺序结构顺序结构是一组按照书写顺序执行的语句结构,这种语句结构的执行流程是按顺序地从一个处理过程转向下一个处理过程。2.选择结构选择结构又称为分支结构。当程序执行到分支判断的语句时,首先判断条件,然后根据条件表达式的结果选择相应的语句执行。分支结构包括......
  • Java基础04:数据类型拓展
    整型拓展十进制整数,如:99,-500,0。八进制整数,要求以0开头,如:015。十六进制数,要求0x或0X开头,如:0x15。//整型inti=10;inti2=010;inti3=0x10;System.out.println(i);//10System.out.println(i2);//8System.out.println(i3);//16浮点型拓展浮点类型float,d......
  • java-隐式转换(自动类型提升)与强制类型转换
    前言在学习运算符的时候会遇到两个名词,一个是隐式类型转换,一个是强制类型转换隐式类型转换也就是取值范围小的数值赋值给取值范围大的变量inta=10;doubleb=a;强制类型转换就是将取值范围大的一个数值直接赋值给取值范围小的变量doubleb=10......
  • Java中常用的util类库在Maven
    Java中常用的util类库在Maven项目中通常以依赖的形式引入。以下是一些常用的util库及其Maven依赖。ApacheCommonsLang3:提供了很多工具类,如StringUtils,ArrayUtils等。<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artif......
  • [深入理解Java虚拟机]线程
    Java与协程在Java时代的早期,Java语言抽象出来隐藏了各种操作系统线程差异性的统一线程接口,这曾经是它区别于其他编程语言的一大优势。在此基础上,涌现过无数多线程的应用与框架,譬如在网页访问时,HTTP请求可以直接与ServletAPI中的一条处理线程绑定在一起,以“一对一服务”的方式处......
  • [深入理解Java虚拟机]HotSpot虚拟机对象
    对象的创建Java是一门面向对象的编程语言,Java程序运行过程中无时无刻都有对象被创建出来。在语言层面上,创建对象通常(例外:复制、反序列化)仅仅是一个new关键字而已,而在虚拟机中,对象(文中讨论的对象限于普通Java对象,不包括数组和Class对象等)的创建又是怎样一个过程呢?当Java虚拟机遇......
  • Java 基础 - 黑马
    StringAPIArrayListEnumObjectStringBuilderStringBufferStringJoinerMathSystempublicclassMain{publicstaticvoidmain(String[]args){//1.System.exit(0);//不要这样玩//2.currentTimeMills:long->1970-1-10:0:01s=1......
  • 基于javaweb jsp ssm图书管理系统的设计与实现+vue录像(源码+lw+部署文档+讲解等)
    前言......