• JavaSE学习----(九)线程(1)



    在这里插入图片描述

    一.什么是进程?什么是线程?

    • 进程是一个应用程序(一个进程是一个软件)
    • 线程是一个进程中执行的执行场景/执行单元
    • 一个进程可以启动多个线程

    二.线程解释

    对于java程序来说,在dos窗口中输入:
    java helloworld 回车之后
    会先启动JVM,而JVM就是一个进程,JVM再启动一个主线程调用一个main方法
    同时再启动一个垃圾回收线程负责看护,回收垃圾,现在的java程序中至少有两个线程并发

    三.进程和线程是什么关系?

    举个例子

    • 某公司A:进程
      某公司CEO:该公司的一个线程
      某公司人事:该公司的一个线程
    • 某公司B:进程
      某公司董事:该公司的一个线程
      某公司人事:该公司的一个线程

    注意:进程A和进程B的内存不共享。在java语言中:线程A和线程B,堆内存和方法区内存共享。但是栈内存独立,一个线程一个栈。

    假设启动十个线程,会有十个栈空间,每个栈和每个栈之间,互不干扰。各自执行各的,这就是多线程并发。

    • 火车站:进程
      窗口一:线程1
      窗口二:线程2
      窗口三:线程3

    火车站中的每一个售票窗口可以看作一个个线程,我在窗口一买票,你可以在窗口二买票,你不需要等我,我也不需要等你,所以多线程并发可以提高效率。

    四.思考

    使用了多线程机制后,main方法结束,是不是有可能程序也不会结束
    main方法结束之后只是主线程结束了,主栈空了,其他栈(线程)可能还在弹栈压栈。
    在这里插入图片描述

    五.对于单核的CPU来说,真的可以做到真正的多线程并发吗?

    • 什么是真正的多线程并发
      t1线程执行t1的,t2线程执行t2的,互不影响,这叫做真正的多线程并发,

    • 单核的CPU只有一个大脑,所以不能够做到真正的多线程并发,但是可以给到人一种“多线程并发”的感觉。

    • 对于单核的CPU来说,在某一个时间点上实际上只能处理一件事情,但是由于CPU处理速度极快,多个线程之间频繁切换执行,给人的感觉是多个事情同时在做。

      • 线程A:播放音乐
      • 线程B:运行游戏

      线程A和线程频繁切换执行,人会感觉音乐一直在播放,游戏一直在打,给我们的感觉是同时并发的。

      • 对于多核的CPU电脑来说,真正的多线程并发是没问题的。【4核CPU表示同一时间可以真正的有4个进程并发执行】

    六. Java语言中实现线程的两种方式

    • 第一种方式:编写一个类,直接继承java.lang.Thread,重写run方法
    MyThread myThread = new MyThread();
    //启动线程
    //start()方法的作用是:启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码任务完成之后,瞬间就结束了
    //这段代码的任务只是为了开辟一个新的栈空间,只要新的栈空间开出来,start()方法就结束了。线程就启动成功了。
    //启动成功的线程会自动调用run方法,并且run方法在分支栈的底部(压栈)
    //run方法在分支栈的地步,main方法在主栈的栈底部。run和main是平级的。
    myThread.start();
    //这里的代码还是运行在主线程中
    
    for(int = i; i<1000;i++){
    System.out.println("主线程---->"+i);
    }   
    
    class  MyThread extends Thread{
    @override
    public void run(){
    //编写程序,这段程序运行在分支线程中(分支栈)
    		for(int i = 0;i<1000;i++){
    			System.out.println("分支线程---->"+i)
    }
    
    }
    
    }                                                                                                                                                                                                                      
    

    在这里插入图片描述

    • run和start的区别
      在这里插入图片描述

    • 第二种方式:编写一个类,实现java.lang.Runnable接口,实现run方法
      在这里插入图片描述

    • 总结
      在这里插入图片描述
      第二种方式实现接口比较常用,因为一个类实现了接口,它还可以去继承其他的类,更灵活

    • 采用创建匿名内部类的方式可以吗?
      在这里插入图片描述

    七.线程图

    在这里插入图片描述

    八.关于线程的睡眠与终止

    1.关于线程的sleep方法

    static void sleep(long millis)

    • 静态方法
    • 参数是毫秒
    • 作用是:让当前线程进入休眠,进入“阻塞状态”,放弃占有的CPU时间片,让给其他线程用
    • Thread.sleep()可以做到这样的效果:间隔特定的时间,去执行一段特定的代码,每隔多久执行一次
      在这里插入图片描述
      在这里插入图片描述
    • 关于sleep的一个面试题!!
      请添加图片描述
      在这里插入图片描述

    2.终止线程的睡眠

    注意:这个不是中断线程的执行,是终止线程的睡眠。
    在这里插入图片描述
    在这里插入图片描述

    3.强行终止线程的执行

    • t.stop() 【已过时,不建议使用】
    • stop()方法缺点:会丢失数据,因为这种方式是直接将线程杀死,不建议使用

    4.合理的终止一个线程的执行

    在这里插入图片描述
    在这里插入图片描述

    九.(了解)关于线程的调度

    1.常见的线程调度模型有哪些?

    • 抢占式线程调度模型:哪个线程的优先级比较高,抢到的CPU时间片概率就高一点/多一点,java采用的就是抢占式调度模型。
    • 均分式调度模型:平均分配CPU时间片每个线程占有的CPU时间片时间长度一样。平均分配,一切平等。有一些编程语言,线程调度模型采用的是这种方式。

    2.java中提供了哪些方法是和线程调度有关系的呢?

    • 实例方法
      void setPriority(int newPriority)//设置线程的优先级
      int getPriority()//获取线程的优先级
      最低优先级 1
      默认优先级 5
      最高优先级 10
      优先级高的获取CPU时间片可能会多一些(但也不完全是,大概率是)

    • 静态方法
      static void yield()//让位方法
      暂停当前正在执行的线程对象,并执行其他线程
      yield()方法不是阻塞方法,让当前线程让位,让给其他线程使用
      yield()方法的执行会让当前线程从“运行状态”回到“就绪状态”
      注意:在回到就绪之后,有可能还会抢到

    • 实例方法:void join()//合并线程

    十.(重点!)关于多线程并发环境下,数据的安全问题

    1.为什么是重点?

    以后在开发中,我们的项目都是运行在服务器当中,而服务器已经将线程定义,线程对象的创建,线程的启动等都已经实现完了,这些代码我们都不需要编写

    最重要的是:你要知道,你编写的程序要放到一个多线程下的环境下去运行,你更需要关注的是这些数据在多线程并发的环境写是否是安全的(重点!!!)

    2.什么时候数据在多线程并发的环境下会存在安全问题呢?

    三个条件

    • 1.多线程并发
    • 2.有共享数据
    • 3.共享数据有修改的行为
      满足以上三个条件就会存在线程安全问题。

    3.怎么解决线程安全问题?

    当多线程并发的环境下,有共享数据,并且这个数据还会被修改,此时就存在线程安全问题,怎么解决这个问题?
    线程排队执行(不能并发)
     用排队执行解决线程安全问题
    这种机制叫做:线程同步机制

    专业术语叫做:==线程同步,==实际上就是线程不能并发了,线程必须排队执行。
    线程同步就是线程排队了,线程排队会牺牲一部分效率,没办法,数据安全第一位。

    在这里插入图片描述

  • 相关阅读:
    JTS: 15 Angle 角度计算
    如何写好代码
    vue项目中内嵌iframe,打包上线时候iframe地址如何写?
    mysql_config_editor的配置
    非线性光学散射偏微分方程组的matlab求解仿真
    Matlab图像处理-HSV
    我为什么更推荐你使用cmake编译grpc程序?
    开源vs闭源大模型如何塑造技术的未来?开源模型的优劣势&未来发展方向
    Flume实践案例
    深入探讨Docker生态系统,Docker Compose vs. Docker Swarm vs. Kubernetes:深入比较
  • 原文地址:https://blog.csdn.net/qq_61899969/article/details/126956669