一. 线程的创建方式
1.1 继承 Thread 类
重写 run() 方法即可.
- public class MyThread extends Thread {
- @Override
- public void run() {
- System.out.println("MyThread is running!");
- }
- public static void main(String[] args) {
- MyThread myThread = new MyThread();
- myThread.start();
- }
- }
1.2 实现 Runnable 接口
- public class MyRunnable implements Runnable {
- @Override
- public void run() {
- System.out.println("MyRunnable is running");
- }
- public static void main(String[] args) {
- Thread myRunnable = new Thread(new MyRunnable());
- myRunnable.start();
- }
- }
2 线程的 5 个状态
新建
当用 new 操作符创建一个线程对象后, 如 new Thread(r), 还没有调用 start() 方法之前的状态
可运行
调用 start() 方法之后且没有被阻塞, 也没在等待某个条件. 可能正在运行也可能没有运行 (等待 CPU 时间片). 在 CPU 分配时间片给多个线程, 使它们轮流执行的过程中, 不过实际有没有运行都处于可运行状态.
阻塞
当一个线程视图获取一个内部对象锁 (synchronized), 而该锁被其它线程持有, 则该线程进入阻塞状态. 内部对象锁是使用 monitor 对象实现的, 每个 monitor 维持两个队列, 一个是 entry_list, 一个 wait_list. 分别用于保存想获取锁的线程和等待条件的线程.(wait_list 中的线程处于等待态).
等待
等待一个条件时. 1.Object.wait 方法, 进入 wait_list 队列, 等待调用 Object.notify() 或 Object.notifyAll() 方法. 2. 等待 ReentryLock 或 Condition 时. 3. 调用 Thread.join() 方法
计时等待
有几个方法有一个超时参数. 调用它们导致线程进入计时等待状态. 这一状态将一直保持到超时期满或者接收到适当的通知.
这些方法有: Thread.sleep,Object.wait,Thread.join,Lock.tryLock,Condition.await 等方法的计时版.
终止
线程因两个原因之一被终止
因为 run 方法正常退出而自然结束
因为一个没有捕获的异常终止了 run 方法而意外死亡
3 Object 类中线程相关的方法
3.1 wait() 方法
线程调用一个对象的 wait() 方法之前需要先获取到这个对象的内部对象锁, 否则会抛出 IllegalMonitorStateException 异常. 另一个可能的异常是: InterruptedException
调用这个方法使线程进入等待状态, 在对象 monitor 对象的等待队列里默默等待, 别的线程调用 notify() 或 notifyAll() 方法来唤醒. 并且会释放获取到当前对象的锁.
这个方法常常用来等待某个条件的满足:
- synchronized(obj) {
- while(条件不满足) {
- obj.wait()
- }
- // 满足条件了, 尽情干想干的事吧!
- }
它还有个带计时的版本 wait(long timeout), 这是个 native 方法, 是 wait 的真正实现. 其实 wait 的实现就是调用了 wait(0) 而已.
3.2 notify() 方法
和 wait() 方法配合使用. 随机唤醒在对象 monitor 等待队列中一个线程.
同样需要先获取内部对象锁才能调用, 否则会抛出 IllegalMonitorStateException 异常.
唤醒只是将线程从等待态切换到 Runnable(可运行) 态, 不一定保证能立马执行 (还有 CPU 分配时间片的因素)
调用此方法不会释放内部对象锁.
3.3 notifyAll()
唤醒所有的等待线程.
调用此方法需要先获取内部对象锁.
调用此方法不会四方内部对象锁.
4 Thread 类中线程相关的方法
4.1 sleep(long millis) 方法
方法声明:
public static native void sleep(long millis) throws InterruptedException;
是个静态方法, 通过 Thread.sleep() 调用. 使当前线程休眠指定时间再进入 runnable 状态. 调用后进入阻塞态, 不会释放内部对象锁.
4.2 join() 方法
方法声明:
public final void join() throws InterruptedException ;
当前线程调用指定线程的 join() 方法, 会等待该线程结束后再继续执行.
join 方法还有一个带参数的版本, 等待线程结束或到达指定时间再继续执行.
调用 join 后进入阻塞状态.
来源: http://www.jianshu.com/p/497681f0bc88