启动
Thread和Runnable可以通过Thread的start()方法进行操作。 Callable类可以通过将对象放入到线程池中调用Submit方法执行,然后获取结果。
sleep
sleep是Thread提供的方法,需要传入时间参数。sleep() 可能会抛出 InterruptedException,因为异常不能跨线程传播回 main() 中,因此必须在本地进行处理。线程中抛出的其它异常也同样需要在本地进行处理。
yield
对静态方法 Thread.yield() 的调用声明了当前线程已经完成了生命周期中最重要的部分,可以切换给其它线程来执行。该方法只是对线程调度器的一个建议,而且也只是建议具有相同优先级的其它线程可以运行。
终止
线程的终止分为多种情况:
- 线程正常运行结束
- 执行到了exit()这种退出标志符
- 使用Stop方法,这种方法是暴力的并且是不安全的。如果在调用
thread.stop()后导致了该线程所持有的所有锁的突然释放(不可控制),那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。所以该方法被废弃了 - 同stop方法,suspend和resume都被废弃了
- interrupt。目前使用的方法。通知线程应该中断了。
interrupt的使用:
- 如果线程是阻塞状态,调用interrupt,线程退出阻塞状态并抛出
InterruptException异常。 - 如果线程正常活动,那么线程的中断标志位设为true,被设置的线程继续运行不受影响。之后线程自行配合。
interrupt并不能终止线程,需要调用的线程配合才行。
join
在线程中调用另一个线程的 join() 方法,会将当前线程挂起,而不是忙等待,直到目标线程结束。
wait、notify、notifyall
wait是Object类中的方法,不是Thread类中的方法,调用 wait() 使得线程等待某个条件满足,线程在等待时会被挂起,当其他线程的运行使得这个条件满足时,其它线程会调用 notify() 或者 notifyAll() 来唤醒挂起的线程。
只能用在同步方法或者同步控制块中使用,否则会在运行时抛出 IllegalMonitorStateException。
使用 wait() 挂起期间,线程会释放锁。这是因为,如果没有释放锁,那么其它线程就无法进入对象的同步方法或者同步控制块中,那么就无法执行 notify() 或者 notifyAll() 来唤醒挂起的线程,造成死锁。
notify和notifyall都是用于唤醒调用wait方法的线程的,不同的是notify方法唤醒一个,而notifyall方法将会唤醒所有该状态下的线程,让他们去竞争锁资源。
wait和sleep的区别:
- wait() 是 Object 的方法,而 sleep() 是 Thread 的静态方法;
- wait() 会释放锁,sleep() 不会。