java的Thread类中包含了一个线程状态枚举类:State
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:
*
* - {@link Object#wait() Object.wait} with no timeout
* - {@link #join() Thread.join} with no timeout
* - {@link LockSupport#park() LockSupport.park}
*
*
* A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called Object.wait()
* on an object is waiting for another thread to call
* Object.notify() or Object.notifyAll() on
* that object. A thread that has called Thread.join()
* 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:
*
* - {@link #sleep Thread.sleep}
* - {@link Object#wait(long) Object.wait} with timeout
* - {@link #join(long) Thread.join} with timeout
* - {@link LockSupport#parkNanos LockSupport.parkNanos}
* - {@link LockSupport#parkUntil LockSupport.parkUntil}
*
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
一共六种状态:
(1)New-新生:至今尚未启动的线程,new Thread方式创建
(2)Runnable-可运行:正在 Java 虚拟机中执行(不是运行)的线程, 是否在运行取决于系统是否分配时间片给他
(3)Blocked-被阻塞:等待对象锁
(4)Waiting-等待:无限期地等待某个线程条件的线程,关联操作:Object.wait和Thread.join或者是concurrent库中Lock的Contidion
(5)Timed waiting-计时等待:限期地等待某个线程条件的线程,关联操作:Thread.sleep、Object.wait、Thread.join、Lock.tryLock和Condition.await
(6)Terminated-被终止:已退出的线程,run执行完,或者由一个未捕获异常意外退出
在给定时间点上,一个线程只能处于一种状态。这些状态是虚拟机状态,它们并没有反映所有操作系统线程状态。所以说这是java的线程状态和大学操作系统课本说的不完全一样。
牢记着六个状态,便与学习java线程的各类行为及相应API的关联。
Block与Wait都是停止运行,并释放CPU执行权,两者有区别么?
(1)优先级:setPriority设置等级1-10。yield让出线程。许多书上都说yield只会将线程让给优先级相对高的,可以源码注释是”allow other threads to execute“,并没有优先级要求,测试下:
public class PriorityYeild extends Thread{
public static void main(String[] args) {
Thread a = new PriorityYeild("A");
a.setPriority(6);
a.start();
Thread b = new PriorityYeild("B");
b.setPriority(4);
b.start();
/*while(true){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(a.getState());//sleep时,状态为TIMED_WAITING
}*/
}
@Override
public void run(){
int i=0;
while(i<20){
i++;
System.out.println(Thread.currentThread().getName()+"------------------"+i);
if(i==10){
Thread.yield();
/*try {
Thread.sleep(10000);//测试睡眠线程的线程状态
} catch (InterruptedException e) {
e.printStackTrace();
}*/
}
}
}
public PriorityYeild(String name) {
super(name);
}
}
结果:多次测试发现,A线程也可能让步给优先级更低的B。yield和优先级无关,之后线程将有谁占有,完全取决于线程调度器。
注:sleep()和yield()的区别:sleep()使当前线程进入Timed waiting状态,所以执行sleep()的线程在指定的时间内肯定不会被执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
(2)守护线程:线程分为:用户线程和守护线程。setDaemon设置是否为守护线程(start前调用),当只剩下守护线程,JVM退出。使用:发送信息,清空垃圾缓存。
public class DaemonThread extends Thread{
@Override
public void run(){
while(true){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(df.format(System.currentTimeMillis()));//报时
}
}
public static void main(String[] args) {
DaemonThread dThread = new DaemonThread();
dThread.setDaemon(true);
dThread.start();
Scanner scanner = new Scanner(System.in);
scanner.next();//等待输入,输入后main主线程退出
Runtime.getRuntime().addShutdownHook(new Thread(){//JVM退出时执行
@Override
public void run(){
System.out.println("JVM exit...");
}
});
}
}
结果:
2014-11-27 10:52:16
2014-11-27 10:52:19
2014-11-27 10:52:22
2014-11-27 10:52:25
1
JVM exit...
(3)线程组:ThreadGroup可以统一管理的线程集合。默认创建线程属于同一个组。
(4)未捕获异常处理器:实现Thread.UncaughtExceptionHandler接口。其实线程组ThreadGroup就实现了该接口。源码处理逻辑:
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);//先执行父类
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();//获取未捕获异常的默认处理器
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
System.err.print("Exception in thread \""
+ t.getName() + "\" ");
e.printStackTrace(System.err);//打印错误异常信息
}
}
}
爱家人,爱生活,爱设计,爱编程,拥抱精彩人生!