0%

多线程

线程的生命周期

  • 线程的生命周期(线程生命周期2.png)

    多线程

  • 线程各个状态

    就绪状态
    创建线程对象后,调用了线程的start()方法(此时线程只是进入了线程队列,等待获取CPU服务(cpu可能正在执行其他程序),具备运行条件,但是并不一定已经开始运行了)

    运行状态
    处于就绪咋混个太的线程,一旦线程获取到CPU的服务之后,就进入到了运行状态,开始执行run()方法里面的逻辑。

    终止
    线程的run()方法执行完毕,或者人为线程调用了stop()方法(该做法已经被淘汰),线程便进入终止状态。

    阻塞
    一个正在执行的线程在某些情况下,由于某种原因而暂时让出了CPU资源,暂停了自己的执行,便进入了阻塞状态,如调用 sleep()方法。

    关于sleep()与wait()的补充说明

    sleep暂停线程,但是监控状态仍然保持,结束后会自动恢复;
    sleep是线程类(Thread)的方法,wait是Object类的方法;
    sleep不释放对象锁,wait放弃对象锁。
    wait后进入等待锁定池,对此对象发出notify或notifyAll()方法后获得对象锁进入运行状态

    线程的分类

  • 用户线程

    运行在前台,执行具体的任务。
    如:程序的主线程,连接网络的子线程等都是用户线程。

  • 守护线程

    运行在后台,为其他前台线程(用户线程)服务。

  • 守护线程的特点:

    一旦所有用户线程都结束运行,守护线程也会随JVM一起结束工作。

  • 守护线程的应用:

    如:数据库连接池中的监测线程(如,监测连接个数与连接超时情况);
    JVM虚拟机启动后的监测线程(如:监测虚拟机内存使用情况、监测程序中持有情况)。
    最常见的守护线程:垃圾回收线程。

  • 设置守护线程

    可以通过调用Thread类的setDaemon(true)方法来设置当前的线程为守护线程。

    注意:

    1.setDaemon(true)必须在start()方法之前调用,否则会抛出IllegalThreadStateException异常。
    即:守护线程的设置一定要放在线程的启动之前。

    2.在守护线程中产生的新线程也是守护线程;

    3.不是所有的任务都可以分配给守护线程来执行,比如读写操作或者计算逻辑。

    原因:一旦所有用户线程都结束运行,守护线程也会随JVM一起结束工作,如果用户线程都结束了,守护线程的读写操作或计算逻辑岂不是要跪…

    线程的创建

  • 1.继承Thread类

      class MyThread extends Thread{
          ......
          @Override
          public void run(){
              ......
          }
      }
      
      MyThread mt = new MyThread();//创建线程
      mt.start();//启动线程
    
  • 2.实现Runnable接口

      class MyThread implements Runnable{
      
          ......
          @Override
          public void run(){
              ......
          }
      }
      
      MyThread mt = new MyThread();
      Thread td = new Thread(mt);//创建线程
      td.start();//启动线程
    
  • 对比总结

    1
    无论用哪种方法,都要new一个Thread类对象,用Thread类的start方法来启动线程。