区分sleep()/wait()/join()/yield()

区分sleep()/wait()/join()/yield()

1.sleep()

  • sleep()是Thread中的静态native方法。
  • sleep()可以在任何情况下调用。Thread.sleep()会暂停当前线程,且不会释放任何锁资源或者monitor。

1.1 举例分析

val obj = Object()

fun main() {
    Thread(RunnableA()).start()
    Thread(RunnableB()).start()
}

class RunnableA:Runnable{
    override fun run() {
        synchronized(obj){
            println("A is start!")
            Thread.sleep(1000)
            println("A is end!")
        }
    }
}

class RunnableB:Runnable{
    override fun run() {
        synchronized(obj){
            println("B is start!")
            Thread.sleep(1000)
            println("B is end!")
        }
    }
}

结果:

A is start!
A is end!
B is start!
B is end!
  • 因为Thread.sleep()不会释放锁资源,所以RunnableA阻塞时仍持有obj的monitor
  • RunnableB只能等待RunnableA执行完毕释放了obj的monitor之后,去获得obj的monitor,然后再执行。

1.2 其他

  • 如果其他的线程中断了一个sleep的线程,sleep方法会抛出Interrupted Exception

2.wait()

  • wait()是Object中定义的native方法。
  • wait()只能在synchronized block中调用,会释放monitor。

2.1 notify()和 notifyAll()

  • 当调用wait()方法后,需要通过调用notify()/notifyAll()来唤醒

2.2 举例分析

val obj = Object()

fun main() {
    Thread(RunnableA()).start()
    Thread(RunnableB()).start()
}

class RunnableA:Runnable{
    override fun run() {
        synchronized(obj){
            println("A is start!")
            obj.wait()
            println("A is end!")
        }
    }
}

class RunnableB:Runnable{
    override fun run() {
        synchronized(obj){
            println("B is start!")
            obj.notify()
            println("B is end!")
        }
    }
}

结果:

A is start!
B is start!
B is end!
A is end!
  • RunnableA在执行到obj.wait()时会将当前线程挂起,并释放obj的monitor。接下来RunnableB获得到obj的monitor之后开始执行。
  • RunnableB在执行到obj.notify()时,会唤醒RunnableA,但是此时RunnableB仍持有obj的monitor。
  • 在RunnableB执行完,释放obj的monitor之后,RunnableA获取到obj的monitor,开始执行剩余部分。
  • 注意:如果RunnableA不能被唤醒,那么即使obj的monitor无人持有,RunnableA也会一直等待,不会去竞争monitor资源。

3.yield()

  • Thread.yield()方法的作用是放弃当前线程获取CPU的执行权,将让其它的线程去获取。
  • 结果是不固定的,有可能一个线程刚放弃CPU的执行权,CPU又将执行权分配给该线程了。

4.join()

  • Thread.join()方法的作用是等待这个线程结束

4.1 举例分析

val threadA = Thread(RunnableA())
val threadB = Thread(RunnableB())

fun main() {
    threadA.start()
    threadB.start()
}

class RunnableA : Runnable {
    override fun run() {
        println("A is start!")
        threadB.join()
        println("A is end!")
    }
}

class RunnableB : Runnable {
    override fun run() {
            println("B is start!")
            Thread.sleep(2000)
            println("B is end!")
    }
}
  • 结果:
A is start!
B is start!
B is end!
A is end!
  • 当RunnableA执行到threadB.join(),会挂起。
  • RunnableB执行完毕会去唤醒thradA,然后RunnableA继续执行。

5.线程状态转换

线程状态转换

参考资料

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值