一.线程的状态
1.NEW:刚刚创建的线程,线程还没有运行等该调用线程的start();
2.RUNNABLE:这个状态的线程正在虚拟机中执行,但是它可能在等待系统其他资源。
3.BLOCKED:线程遇到同步代码,需要进入临界区获取资源权限,这时就进入阻塞状态,等获取到资源权限后,方可继续运行。
4.WAITING/TIMED_WAITING:都表示等待,区别是WAITING进入的是一个无限期的等待状态。TIME_WAITING:进入的是一个有时间限制的等待。
5.TERMINATED:终止状态,指一个线程运行完毕,进入消亡状态。
二:如果新建线程
方法一:直接new出线程,然后必须调用start方法才能开启线程,但是这个线程什么事都没有做。
Thread t1=new Thread();
t1.start();
方法二:方法一创建的线程什么都没有做,所以引入了第二种创建线程的方法,在new Thread的时候传入一个匿名内部类并且重写它的run方法,再去调用该线程的start方法,默认thread.run方法调用的就是传入的runnable的run方法。
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
// 做你自己的事
}
});
thread1.start();
方法三:使用Runnable接口来定义Thread,比起重写Thread.run方法要好的多,并且是比较常用和推荐的方法。
public class Thread3 implements Runnable {
public static void main(String[] args) {
Thread t1=new Thread(new CreateThread3());
t1.start();
}
@Override
public void run() {
System.out.println(" I am Runnable");
} }
三.如何正确的终止线程
stop():立即终止线程,并且释放锁。如果多线程环境中,当前线程被此方法暴力终止,会导致某个操作执行不完全。而其它线程会继续执行,会造成不可预知的风险。
stopMe():新建stopMe方法,设置停止标识,在线程run方法中通过判断此标识做好线程收尾工作退出线程,这样既可以退出线程,又不会写坏数据。
四.线程中断
线程中断是一种线程间协调合作的重要方法,不能响应中断的线程注定在高并发环境中不能获得优异的性能表现。线程中断不是线程中止运行,而是在原地等待唤醒继续执行。
···
Thread thread = new Thread();
thread.start();
thread.isInterrupted(); 该方法判断当前线程是否被中断,不会清除中断标志;
thread.interrupt();中断当前线程,标记中断位;
Thread.interrupted();静态方法,判断当前线程是否被中断,并且清除中断位;
注意如果Thread的sleep方法抛出异常会清楚中断位,如果此异常被捕获处理时,要考虑是否需要重新设置中断位
···
五.等待(wait)与通知(notify/notifyAll)
调用obj的wait和notify方法必须要先获取obj的monitor,当A线程调用wait方法后会释放obj的monitor,接着A线程会进入waiting状态,在原地等待再次获取obj的monitor。等其它线程B调用obj的notify方法后,A线程并不能马上执行,因为A线程需要先获取obj的monitor,所以B线程必须执行完它的synchronized代码块,A才有机会获取obj的monitor。
六.挂起(suspend)和回复(resume)
线程的suspend和resume是一对相反的操作,suspend的线程必须调用resume才能继续执行。但是这对方法已被弃用,因为suspend操作并不释放资源会造成资源过度占用问题;
7.等待线程结束(join)和谦让(yield)
join方法:A线程的join的本质是让当前线程在A线程上不停的等待,等待A线程执行完。
yield方法:yield方法是静态方法,此方法会让出当前线程的CPU时间,如果某个线程优先级很低,可以使用此方法让出CPU资源。此方法调用后,当前线程还是会继续争夺CPU。