Loading

线程中常见的方法

start()

启动一个新的线程,在新的线程中运行run()方法中的代码
start方法只是让线程进入就绪状态,不是马上运行。需要等待CPU的时间片分给它
一个线程的 start 方法只能调用一次,如果多次调用会抛出IllegalThreadStateException

run()

新线程启动后会调用的方法,如果在构造 Thread 对象时传递了 Runnable,线程启动后会调用 Runnable 中的 run 方法,否则默认不执行任何操作

image

如果同时传递 Runnable 和重写 run 方法,那么会执行的当然是重写的 run 方法

image

join()

等待某个线程结束

如下代码:

image

主线程直接获取a的值,得到的是0

image

如果我们想要读取到t1修改a的值,那么就需要使用join()

image

image

join内部是用wait方法实现的

join如果不带时间,那就是一直等。如果带了时间,那就是如果时间到了还没线程还没结束,那么就继续了,不等了

image

image

yield()

调用 yield 方法会调度执行其他同优先级的线程。如果这时没有其他同优先级的线程,那么不能保证让当前线程暂停

yield 的作用只相当于提示,并不保证一定有效果,具体的实现依赖于操作系统的任务调度器

这个方法的主要作用在于测试和调试

image

sleep()

这个方法很熟悉了,使线程暂停一段时间,如果持有锁,那么 sleep 时也不会释放锁

image

wait()

必须持有锁才能调用此方法,否则会抛出IllegalMonitorStateException。作用在于当一个线程获取锁之后,发现当前不满足执行条件,空等又浪费资源,所以使用 wait 方法释放锁,自己进入 Monito r中 waitset 中等待被 notify 和 notifyall 唤醒。释放锁之后,其他线程抢到锁成为 owner ,没抢到的继续阻塞

wait 方法并不是 Thread 类中的方法,而是 Object 的方法

为什么这些操作线程的方法要定义在 Object 类中呢?

简单说:因为 synchronized 中的这把锁可以是任意对象,所以任意对象都可以调用 wait() 和 notify() ;所以 wait 和 notify 属于 Object 。

专业说:因为这些方法在操作同步线程时,都必须要标识它们操作线程的锁,只有同一个锁上的被等待线程,可以被同一个锁上的 notify 唤醒,不可以对不同锁中的线程进行唤醒

也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法是定义在Object类中

sleep 和 wait 的区别

  • sleep 是 Thread 方法,而 wait 是 Object 的方法
  • sleep 不需要强制和 synchronized 配合使用,但 wait 需要和 synchronized 一起用,也就是上面说的一定要获取到锁
  • sleep 如果获取到了锁,不会释放,但是wait会释放锁

interrupt()

打断线程

如果被打断线程正在 sleep,wait,join 会导致被打断的线程抛出InterruptedException,并清除打断标记
如果打断正在运行的线程,则会设置打断标记

isInterrupted:判断是否被打断,不会清除打断标记

interrupted:判断是否被打断,会清除打断标记

posted @ 2021-06-20 17:21  Xianhao  阅读(74)  评论(0编辑  收藏  举报