sleep和wait有什么区别?(附线程唤醒 *** 作)

sleep和wait有什么区别?(附线程唤醒 *** 作),第1张

目录

1、Java线程休眠 *** 作

1.1、sleep休眠(让线程阻塞一段时间)

1.2、wait休眠(用于线程之间的通信)

1.3、wait VS sleep

2、Java线程唤醒 *** 作

2.1 notify唤醒 *** 作

2.2 notifyAll唤醒 *** 作

3、注意事项


1、Java线程休眠 *** 作

1.1、sleep休眠(让线程阻塞一段时间)

1.1.1方法说明:

1.1.2代码实现

import java.time.LocalTime;

/**
 * sleep休眠演示
 */
public class ThreadSleep2 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            try {
                //休眠前时间点
                System.out.println(LocalTime.now());
                //休眠2s
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //休眠后时间点
            System.out.println(LocalTime.now());
        });
        thread.start();

    }
}

以上代码运行结果:

//休眠前时间点
21:13:07.630
//休眠后时间点
21:13:09.643

1.1.3:源码实现原理

public static native void sleep(long millis) throws InterruptedException;
1.2、wait休眠(用于线程之间的通信)

1.2.1:wait 执⾏流程

· 使当前执⾏代码的线程进⾏等待. (把线程放到等待队列中)
· 释放当前的锁
· 满⾜⼀定条件时被唤醒, 重新尝试获取这个锁


*wait 要搭配 synchronized 来使⽤. 脱离 synchronized 使⽤ wait 会直接抛出异常.
 

1.2.2 wait 结束等待的条件

· 其他线程调⽤该对象的 notify ⽅法.
· wait 等待时间超时 (wait ⽅法提供⼀个带有 timeout 参数的版本, 来指定等待时间).
· 其他线程调⽤该等待线程的 interrupted ⽅法, 导致 wait 抛出 InterruptedException 异常

1.2.3 代码实现

import java.time.LocalTime;

/**
 * wait 使用
 */
public class WaitDemo {
    public static void main(String[] args) {
        Object lock = new Object();

        Thread t1 = new  Thread(()->{
            System.out.println("线程1开始执行");
            try {
                synchronized (lock) {
                    System.out.println(LocalTime.now());
                    //等待3s
                    lock.wait(3000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程1执行完成");
            System.out.println(LocalTime.now());

        },"线程1");
        t1.start();
    }
}

以上代码运行结果:

//线程1开始执行
21:46:26.859
//线程1执行完成
21:46:29.871

1.2.4 源码实现原理:

public final native void wait(long timeout) throws InterruptedException;

1.3、wait VS sleep

1.3.1:相同点:

        · 都是可以让线程进入休眠状态。

        · 都可以响应Interrupte(中断)的请求。

1.3.2: 不同点:

        · wait释放锁;而sleep不释放锁。

        · wait必须配合synchronized一起使用;而sleep不需要。

        · wait可以不传参;而sleep必须要传递一个数值类型的参数。

        · wait属于Obiect(对象)的方法;而sleep属于Thread(线程)的方法。

        · wait方法无参让线程进入了WAITING状态;sleep让线程进入到TIMED_WAITING状态。

        · wait可以接收notify/notifyAll之后就执行;而一般情况下,sleep只能等待超时时间之后再恢              复执行

2、Java线程唤醒 *** 作

2.1 notify唤醒 *** 作

2.1.1 notify使用

notify ⽅法是唤醒等待的线程:
⽅法notify()也要在同步⽅法或同步块中调⽤,该⽅法是⽤来通知那些可能等待该对象的对象锁的其
它线程,对其发出通知notify,并使它们重新获取该对象的对象锁。
如果有多个线程等待,则有线程调度器随机挑选出⼀个呈 wait 状态的线程。(并没有 "先来后到")
在notify()⽅法后,当前线程不会⻢上释放该对象锁,要等到执⾏notify()⽅法的线程将程序执⾏
完,也就是退出同步代码块之后才会释放对象锁
 

2.1.2代码实现

public static void main(String[] args) throws InterruptedException {
      Object lock = new Object();
       Thread t1 = new Thread(() -> {
         synchronized (lock) {
           System.out.println("开始执⾏线程1");
         try {
           lock.wait();
     } catch (InterruptedException e) {
          e.printStackTrace();
     }
      System.out.println("线程1执⾏完成");
     }
     });
        t1.start();
    synchronized (lock) {
        lock.notify();
    }
}

2.2 notifyAll唤醒 *** 作

2.2.1 notifyAll使用

notify⽅法只是唤醒某⼀个等待线程. 使⽤notifyAll⽅法可以⼀次唤醒所有的等待线程
 

2.2.2 代码实现

public static void main(String[] args) throws InterruptedException {
       Object lock = new Object();
       Thread t1 = new Thread(() -> {
           synchronized (lock) {
              System.out.println("开始执⾏线程1");
               try {
                   lock.wait();
               } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                   System.out.println("线程1执⾏完成");
             }
         });
         t1.start();
         Thread t2 = new Thread(() -> {
             synchronized (lock) {
               System.out.println("开始执⾏线程2");
           try {
                  lock.wait();
           } catch (InterruptedException e) {
                 e.printStackTrace();
             }
            System.out.println("线程2执⾏完成");
        }
     });
     t2.start();
     Thread.sleep(1000);
     System.out.println("唤醒线程");
     synchronized (lock) {
          lock.notifyAll();
     }
}

3、注意事项

1. wait 使⽤前必须要加锁。
2. wait 和 synchronized 必须使⽤同⼀把锁,不然会报错。
3. notifyAll 并不是唤醒所有 wait 的对象,⽽是唤醒当前对象所有 wait 的对象。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/728814.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存