JUC(一):线程基础知识

113 阅读3分钟

线程基础知识

多线程为什么重要

  1. 硬件方面-摩尔定律失效

    摩尔定律: 它是由英特尔创始人之一Gordon Moore(戈登·摩尔)提出来的。其内容为: 当价格不变时,集成电路上可容纳的元器件的数目约每隔18-24个月便会增加一倍,性能也将提升一倍。 换言之,每一美元所能买到的电脑性能,将每隔18-24个月翻一倍以上。这一定律揭示了信息技术进步的速度。

    可是从2003年开始CPU主频已经不再翻倍,而是采用多核而不是更快的主频。

    摩尔定律失效。

    在主频不再提高且核数在不断增加的情况下,要想让程序更快就要用到并行或并发编程。

  2. 软件方面

    高并发系统,异步+回调等生产需求

Java start一个线程

  1. Java线程理解以及openjdk中的实现

    // Java的底层是C++

    private native void start0();

  2. 更加底层的C++源码解读

    java线程是通过start的方法启动执行的,主要内容在native方法start0中, Openjdk的写JNI一般是一一对应的,Thread.java对应的就是Thread.c start0其实就是JVM_StartThread。此时查看源代码可以看到在jvm.h中找到了声明,jvm.cpp中有实现。

    image-20230101202315666

    jvm.cpp

    image-20230101202454069

    image-20230101202526268

    thread.cpp

    image-20230101202605484

Java多线程相关概念

  1. 进程

    是程序的⼀次执⾏,是系统进⾏资源分配和调度的独⽴单位,每⼀个进程都有它⾃⼰的内存空间和系统资源

  2. 线程

    在同⼀个进程内⼜可以执⾏多个任务,⽽这每⼀个任务我们就可以看做是⼀个线程

    一个进程会有一个或多个线程

  3. 何为进程?何为线程

    image-20230101203014958

    image-20230101203047954

    image-20230101203147978

    image-20230101203210799

    image-20230101203252369

    image-20230101203315741

    image-20230101203338070

    image-20230101203359619

    image-20230101203418844

    image-20230101203440209

  4. 管程-Monitor(监视器),也就是我们平时所说的锁

    Monitor其实是一种同步机制,他的义务是保证(同一时间)只有一个线程可以访问被保护的数据和代码。

    JVM中同步是基于进入和退出监视器对象(Monitor,管程对象)来实现的,每个对象实例都会有一个Monitor对象, Object o = new Object();

    new Thread(() -> { synchronized (o) {

    }

    },"t1").start();

    Monitor对象会和Java对象一同创建并销毁,它底层是由C++语言来实现的。

    image-20230101203623993

  5. 用户线程和守护线程

    1. Java线程分为用户线程和守护线程, 线程的daemon属性为true表示是守护线程,false表示是用户线程

    2. 用户线程

      是系统的工作线程,它会完成这个程序需要完成的业务操作

    3. 守护线程

      是一种特殊的线程,在后台默默地完成一些系统性的服务,比如垃圾回收线程

    4. 代码

      package com.atguigu.itdachang;
      ​
      public class DaemonDemo
      {
      public static void main(String[] args)
      {
          Thread t1 = new Thread(() -> {
              System.out.println(Thread.currentThread().getName()+"\t 开始运行,"+(Thread.currentThread().isDaemon() ? "守护线程":"用户线程"));
              while (true) {
      ​
              }
          }, "t1");
          //线程的daemon属性为true表示是守护线程,false表示是用户线程
          t1.setDaemon(true);
          t1.start();
          //3秒钟后主线程再运行
          try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
      ​
          System.out.println("----------main线程运行完毕");
      }
      ​
      }
      
    5. 总结

      当程序中所有用户线程执行完毕之后,不管守护线程是否结束,系统都会自动退出

      如果用户线程全部结束了,意味着程序需要完成的业务操作已经结束了,系统可以退出 了。所以当系统只剩下守护进程的时候,java虚拟机会自动退出

      注意:设置守护线程,需要在start()方法之前进行