Thread详解
什么是线程
- 进程中负责程序执行的执行单元
- 依靠程序执行的顺序控制流,只能使用程序的资源和环境,共享进程的全部资源
- 有自己的堆栈和局部变量,没有单独的地址空间
- CPU调度和分派的基本单位,持有程序计数器,寄存器,堆栈
生命周期
五种状态
1、新建状态(New)
当线程对象创建后,即进入新建状态;如:Thread t = new MyThread();
2、就绪状态(Runnable)
当调用线程对象的start()方法时,线程即进入就绪状态。处于就绪状态的线程只是说明此线程已经做好准备,随时等待CPU调度执行,并不是说执行了start()方法就立即执行。
3、运行状态(Running)
当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。
4、阻塞状态(Blocked)
处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。
阻塞状态分类
等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程占用),它会进入到同步阻塞状态;
其他阻塞:通过调用线程的sleep()或join()或发出I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5、死亡状态
线程执行完毕或者是异常退出,该线程结束生命周期。
常用方法
1、start()
要想启动多线程必须使用start()方法完成;run()只是普通的方法
2、join()
让父线程等待子线程结束之后才能继续运行。
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new MyTestThread();
Thread thread2 = new MyTestThread();
Thread myTestThread1 = new Thread(thread1, "thread1");
Thread myTestThread2 = new Thread(thread2, "thread2");
myTestThread1.start();
myTestThread2.start();
myTestThread1.join();
System.out.println("结束执行=====");
}
class MyTestThread extends Thread{
public void run(){
System.out.println("Thread.currentThread().getName():" + Thread.currentThread().getName());
}
}
执行结果:
1、Thread.currentThread().getName():thread1
2、结束执行=====
3、Thread.currentThread().getName():thread2
3、sleep()
会让当前的线程暂停一段时间,并进入阻塞状态,调用sleep()并不会释放锁
4、yield()
调用yield()方法之后,从运行状态转换到就绪状态,CPU从就绪状态队列中只会选择与该线程优先级相同或者是优先级更高的线程去执行。
5、wait()、notify()、notifyAll()
wait()是Object中的方法,当线程调用wait()方法,当前线程释放对象锁,进入等待队列。
notify()/notifyAll()是Object中的方法,唤醒在此对象上wait()的单个或者所有线程。
6、interrupt()、interrupted()、isInterrupted()
多线程先明白一个术语“中断状态”,中断状态为true,线程中断。
interrupt():就是通知中止线程的,使“中断状态”为true。
isInterrupted():就是打印中断状态的,然后不对中断状态有任何操作。
interrupted():检测运行这个方法的线程的中断状态,注意,是运行这个方法的线程,且会清除中断状态