Thread的常见属性
属性 | 方法 | 说明 |
---|---|---|
ID | getId() | 线程的唯一标识,不同线程ID不会重复 |
名称 | getName() | 在调试工具中会用到 |
状态 | getState() | 表示线程当前状态 |
优先级 | getPriority() | 优先级高的线程理论上更容易被调度 |
是否后台线程 | isDaemon() | JVM会在一个进程的所有非后台进程结束后,才结束运行 |
是否存活 | isAlive() | run方法是否运行结束 (调用考虑点:非运行态不能执行到这行代码,如阻塞态、就绪态) |
是否中断 | isInterrupted() | 线程是否中断 |
常用方法
start启动线程
- 启动线程必须调用start()。
- run方法 和 start方法不同。
run() 为线程运行态时所执行任务的方法,如果使用Runnable传入构造创建线程,就执行Runnable对象的run方法。
interrupt通知停止运行
通过 thread 对象调用 interrupt() 方法通知该线程停止运行。
thread 收到通知的方式有两种:如果线程调用了 wait/join/sleep 等方法而阻塞挂起,则以InterruptedException 异常的形式通知,清除中断标志。
- 否则,只是内部的一个中断标志被设置,thread 可以通过
- Thread.interrupted() 判断当前线程的中断标志被设置,清除中断标志。
- Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,不清除中断标志。
第二种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。
方法 | 说明 |
---|---|
public void interrupt() | 中断对象关联的线程,如果线程正在阻塞,则以异常方式通知,否则设置标志位 |
public static boolean interrupted() | 判断当前线程的中断标志位是否设置,调用后清除标志位 |
public boolean isInterrupted() | 判断对象关联的线程的中断标志位是否设置,调用后不清除标志位 |
join等待一个线程
作用:当前线程(代码行所在线程)阻塞并等待,直到满足条件后,当前线程继续往下执行。
条件:无参时线程的引用对象执行完毕;有参时为引用线程执行完毕或时间耗完。
方法 | 说明 |
---|---|
public void join() | 等待线程结束 |
public void join(long millis) | 当前线程阻塞并等待引用线程结束,最多等待 millis 毫秒 |
public void join(long millis, int nanos) | 同理,但精度更高 |
join方法底层是调用的Object的wait()方法,wait方法会让线程进入阻塞状态,并且
会释放线程占有的锁
,并交出CPU执行权限。
在main线程中调用thread.join()方法后,main线程会进入等待,然后等待thread执行完之后再继续执行。
sleep线程休眠
作用:让当前线程,休眠给定的时间。
注意:因为线程的调度是不可控的,所以,这个方法只能保证线程真正休眠时间是大于等于休眠时间的。
sleep让线程睡眠,交出CPU,让CPU去执行其他的任务。sleep方法不会释放锁
,也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象。sleep方法相当于让线程进入阻塞状态。
yield让出CPU
调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程。它跟sleep方法类似,同样不会释放锁
。但是yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会。
注意,调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点是和sleep方法不一样的。
线程状态
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
- 线程创建之后,不会立即进入就绪状态,因为线程的运行需要一些条件(比如内存资源),只有线程运行需要的所有条件满足了,才进入就绪状态。
- 当线程进入就绪状态后,不代表立刻就能获取CPU执行时间,也许此时CPU正在执行其他的事情,因此它要等待。当得到CPU执行时间之后,线程便真正进入运行状态。
- 线程在运行状态过程中,可能有多个原因导致当前线程不继续运行下去,比如用户主动让线程睡眠(睡眠一定的时间之后再重新执行)、用户主动让线程等待,或者被同步块给阻塞,此时就对应着多个状态:time waiting(睡眠或等待一定的事件)、waiting(等待被唤醒)、blocked(阻塞)。
- 当由于突然中断或者子任务执行完毕,线程就会被消亡。