线程(五)–sleep和wait的区别

本文详细解析了Java中线程的sleep与wait方法的区别,通过实例演示了两者如何影响对象锁,以及如何影响线程间的同步。通过具体代码展示了在不同情况下,number变量的变化情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.67tgb.com/?p=534

上次我们讲完了锁机制,接下来说一下sleep 和wait对锁的控制。

   sleep方法是Thread类的静态方法,表示在指定的毫秒数内让当前正在执行的线程休眠。

   wait方法则是Object类的普通方法,表示当前线程等待,直到其他线程调用这个对象的notify()或者notifyAll()方法。

   正如在上文中所说的, java引入了同步监视器来解决线程同步问题,使用同步监视器的通用方法就是同步代码块。其语法格式如下:

synchronized (obj) {

 

                  }

   其中obj就是同步监视器,上面代码的含义是:线程开始执行同步代码块之前,必须先获得对同步监视器的锁定。任何时候只能有一条线程可以获得对同步监视器的锁定。同步代码执行结束后,该线程自然释放了对同步监视器的锁定。

   因为wait会对线程的同步监视器进行操作,所以它们必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronized block中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。

   sleep和wait具有使当前线程沉睡的作用,最为重要的一个区别就是sleep是Thread类的静态方法,因此他不能改变对象的锁。 所以当在一个Synchronized方法中调用sleep()时,线程虽然休眠了,但是对象的锁没有被释放,其他线程仍然无法访问这个对象。而wait()方法则会在线程休眠的同时释放掉机锁,其他线程可以访问该对象。

   下面我们通过一个例子,来深入了解一下:

/**

 * Thread sleep和wait区别

 * @author liubing

 *

 */

public class TestSleepAndWait implements Runnable {

    int number = 10;

 

    public void firstMethod() throws Exception {

        synchronized ( this) {

            number += 100;

            System. out.println( number);

        }

    }

 

    public void secondMethod() throws Exception {

        synchronized ( this) {

            /**

             * (休息2S,阻塞线程)

             * 以验证当前线程对象的机锁被占用时,

             * 是否被可以访问其他同步代码块

             */

            //Thread.sleep(2000);

            this.wait(2000);

            number *= 200;

        }

    }

 

    @Override

    public void run() {

        try {

            firstMethod();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

 

    public static void main(String[] args) throws Exception {

      TestSleepAndWait testSleepAndWait = new TestSleepAndWait();

        Thread thread = new Thread(testSleepAndWait);

        thread.start();

        testSleepAndWait.secondMethod();

    }

}

   你能分析出打印的number值是多少吗?

当使用 this.wait(2000) 时,打印的number值是 110

当使用 Thread.sleep(2000)时,打印的number值是2100

  简单分析一下代码:

  这个类有两个同步方法,也就是任何一个方法执行时,TestSleepAndWait类的对象都会被锁定,导致其他方法等待。

1. 我们先来看使用wait方式时的情况:

  主线程main方法开始执行, 调用thread.start()方法时,线程进入就绪状态,等待cpu调度。接下来会调用TestSleepAndWait类的secondMethod()方法,该方法的执行会先于thread的run方法。

  因此,当secondMethod()方法调用时,testSleepAndWait对象首先被main线程锁定,随后主线程进入等待。由于wait方法会使得main线程释放对testSleepAndWait对象的锁定,因此thread线程获得对testSleepAndWait对象的锁定,得到执行机会,run方法开始执行,number初始值10,加上100后,打印出110.

2. 再来看使用sleep方式时的情况:

主线程main方法开始执行, 调用thread.start()方法时,线程进入就绪状态,等待cpu调度。接下来会调用TestSleepAndWait类的secondMethod()方法,该方法的执行会先于thread的run方法。

  因此,当secondMethod()方法调用时,testSleepAndWait对象首先被main线程锁定,随后主线程进入等待。由于sleep方法仍然保持对testSleepAndWait对象的锁定,因此thread线程虽然处于就绪状态,但是由于无法获得对testSleepAndWait对象的锁定,firstMethod()无法执行。

  两秒钟后,main线程继续执行secondMethod()方法,number乘以200变成2000.

secondMethod()方法执行完毕,对象锁被释放。

  此时thread线程终于获得对testSleepAndWait对象的锁定,开始执行firstMethod(),打印出2100.

  不知道你看明白了没有。


### PyCharm 打开文件显示不全的解决方案 当遇到PyCharm打开文件显示不全的情况时,可以尝试以下几种方法来解决问题。 #### 方法一:清理缓存并重启IDE 有时IDE内部缓存可能导致文件加载异常。通过清除缓存再启动程序能够有效改善此状况。具体操作路径为`File -> Invalidate Caches / Restart...`,之后按照提示完成相应动作即可[^1]。 #### 方法二:调整编辑器字体设置 如果是因为字体原因造成的内容显示问题,则可以通过修改编辑区内的文字样式来进行修复。进入`Settings/Preferences | Editor | Font`选项卡内更改合适的字号大小以及启用抗锯齿功能等参数配置[^2]。 #### 方法三:检查项目结构配置 对于某些特定场景下的源码视图缺失现象,可能是由于当前工作空间未能正确识别全部模块所引起。此时应该核查Project Structure里的Content Roots设定项是否涵盖了整个工程根目录;必要时可手动添加遗漏部分,并保存变更生效[^3]。 ```python # 示例代码用于展示如何获取当前项目的根路径,在实际应用中可根据需求调用该函数辅助排查问题 import os def get_project_root(): current_file = os.path.abspath(__file__) project_dir = os.path.dirname(current_file) while not os.path.exists(os.path.join(project_dir, '.idea')): parent_dir = os.path.dirname(project_dir) if parent_dir == project_dir: break project_dir = parent_dir return project_dir print(f"Current Project Root Directory is {get_project_root()}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值