启动线程的2种方式

  1. 1、继承Thread类,重写run方法
  2. class A extends Thread{
  3. @Override
  4. public void run() {
  5. super.run();
  6. }
  7. }
  8. new A().start();
  9. 2、实现Runnable接口,重写run方法
  10. class A implements Runnable{
  11. @Override
  12. public void run() {
  13. System.out.println(Thread.currentThread().getName());
  14. }
  15. }
  16. new Thread(new A()).start();

线程的声明周期

image.png

  1. 1、新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
  2. 2、就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。
  3. 处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,
  4. 并不是说执行了t.start()此线程立即就会执行;
  5. 3、运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,
  6. 即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,
  7. 线程要想进入运行状态执行,首先必须处于就绪状态中;
  8. 4、阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,
  9. 停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。
  10. 根据阻塞产生的原因不同,阻塞状态又可以分为三种:
  11. (1)等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
  12. (2)同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
  13. (3)其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。
  14. sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  15. 5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
  16. 就绪状态转换为运行状态:当此线程得到处理器资源;
  17. 运行状态转换为就绪状态:当此线程主动调用yield()方法或在运行过程中失去处理器资源。
  18. 运行状态转换为死亡状态:当此线程线程执行体执行完毕或发生了异常。
  19. 此处需要特别注意的是:当调用线程的yield()方法时,线程从运行状态转换为就绪状态,
  20. 但接下来CPU调度就绪状态中的哪个线程具有一定的随机性,因此,可能会出现A线程调用了yield()方法后,
  21. 接下来CPU仍然调度了A线程的情况。

start()

  1. 主线程执行start(),请求jvm,启动新线程,线程调度,有空闲则执行。
  2. 准备工作:就绪状态。
  3. 不能重复调用start()方法,会抛出IllegalThreadStateException异常。
  4. start()方法会使得该线程开始执行;java虚拟机会去调用该线程的run()方法。
  5. 最终执行c++的start0()方法。
  6. private native void start0();
  7. 不可以重复调用start()方法。

run()

  1. 这只是一个普通的方法。和普通的方法没有区别。
  2. 所以启动线程,要调用start()方法,然后间接的调用run()方法。
  3. 当通过实现Runnable接口来创建线程时,启动线程会使得run()方法在那个独立执行的线程中被调用。

sleep()

  1. 睡眠。将线程挂起一段时间。时间自己指定。
  2. 该方法不占用CPU,并且规定时间过后自动复活线程。

yield()

  1. 一个线程在运行,另外一个线程也在运行。
  2. CPU层级执行线程,有一个等待队列。
  3. 中间调用该方法,离开一会,进入CPU等待队列。
  4. 该方法可理解为,让出cpu,给其他线程执行,当然也可能继续执行(因为又轮到它了),这要看调度算法。

join()

在本线程里调用本线程的join方法是没有意义的
比如,2个线程,A和B
A线程,执行到中途某个位置,调用了B.join()。
此时,会将B线程加入到A线程,A线程停住,执行完B线程,
再讲A线程剩下的内容执行完。
该方法经常用来等待另一个线程的结束。
也就是等B线程运行结束,A线程才运行完。再比如保证线程的执行顺序等等。

interrupt()

停止线程
使用thread.interrupt();

//这个是真正的中断方法
private native void interrupt0();

配合thread.isInterrupted()使线程中断。
该方法用于检测线程是否中断,是返回true,否返回false。