线程状态
我们在java.lang.Thread类中可以找到一个状态枚举类
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;
}
线程执行
-
java线程模型其实是对应的底层操作系统的线程模型,线程也就是系统的一个资源。 资源是宝贵的,所以线程池使用必不可少的
-
线程的调度模型是抢占式,也就是由cpu来分配时间片,什么时间分配和分配多少由操作系统来分配。
获取到时间片就会去执行,时间片执行完成之后,再继续需要获取时间片分配。
线程中断机制
Java没有提供一种安全、直接的方法来停止某个线程,而是提供了中断机制。 中断机制是一种协作机制,通过给当前线程设置一个中断标识,不过中断标识并不能直接终止另一个线程,而需要被中断的线程自己处理
中断标识
调用线程实例方法t.interrupt()就可以对线程标识一个中断标识interrupt=true.这时候有如下几种情况:
- 当线程处于WAITING,TIMED_WAITING,即调用声明InterruptedException的方法,就可以随即抛出一个InterruptedException。
public static native void sleep(long millis) throws InterruptedException;
public final void wait() throws InterruptedException
- 不响应中断 当线程状态处于BLOCKED状态(特指线程进入synchronized等待队列中),若此时中断标识=true,并不会做出任何事,当线程被notify唤醒并且获取同步锁进入同步块时,也不会主动抛出异常,此时需要在线程中自己根据线程中断状态来处理
Object lock = new Object();
synchronized(lock){
}
- 响应中断
ReentrantLock#lockInterruptibly -> AQS#acquireInterruptibly (所以lockInterruptibly声明了抛出中断异常throws InterruptedException,和sleep/wait类似)
在juc包中AQS类中提供了一个acquireInterruptibly
private void doAcquireInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();//(2)
}
} finally {
if (failed)
cancelAcquire(node);
}
}
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted(); //(1)
}
- 当线程被LockSupport.unpark唤醒之后,会判断是否被中断
- 如果被中断,则会主动抛出InterruptedException
总结: AQS和synchronized区别:
- AQS提供响应中断,唤醒后主动抛出中断异常
- synchronized不响应中断,不会主动抛出中断异常,并且被唤醒后还需要获取同步锁之后,才能处理异常
java有关线程中断三个方法
t.interrupt();
设置线程中断标识flag=true
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
//调用底层native方法,给当前线程标识一个interrupt flag
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
private native void interrupt0();
Thread.interrupted();
public static boolean interrupted() {
return currentThread().isInterrupted(clearInterrupt->true);
}
静态方法。判断当前线程是否中断(即判断flag==true), 如果已经中断,则清空标识 将flag重置为false.
则此时代表线程中断标识为false。
t.isInterrupted();
public boolean isInterrupted() {
return isInterrupted(clearInterrupt->false);
}
判断线程t是否中断(即判断flag==true),不会处理中断标识