线程-第一篇

前言

上一篇了解到进程是可以很好的解决并发编程这样的问题,但在有些场景需要频繁的创建和销毁,此时使用并发编程会让系统开销增大

注:基于多进程的编程模式:服务器同一时刻会收到很多请求,针对每个请求,都会创建一个进程,给这个请求提供一定服务,返回对应的响应;一旦请求处理完进程就要销毁;

若请求过多,服务器需要不停创建新的进程,销毁旧的进程;

频繁创建和销毁,开销增大:资源的申请和释放,进程是资源(CPU,硬盘,内存,网络带宽)分配的基本单位;进程刚启动,内存资源进程需要把依赖的代码和数据从磁盘加载到内存

引入线程可以解决上述问题,线程--"轻量级进程",在进程的基础上做出了改进,保持了独立调度执行--"并发支持",同时省去"分配资源""释放资源"带来的额外开销

线程工作原理

一.PCB描述线程

一个进程可以有多个PCB,表示这个线程包含了一个线程组包含了多个线程(线程组也是进程的一部分) 

操作系统进行"多任务调度"本质上是在调度PCB(线程在系统中的调度规则就和之前的进程是一样的,线程的PCB中也有状态,优先级,上下文,记账信息...)

每个进程,都可以包含一个线程/多个线程

线程要解决的问题:要能够降低频繁释放带来的开销

 二.进程和线程的关系

有线程之前进程需要扮演两个角色(资源分配的基本单位,也是调度执行的基本单位)

有线程之后,进程专注资源分配(创建进程,资源分配,一个进程至少包含一个线程-创建第一个线程的同时,进程就出来了),线程负责调度执行;

加快效率:1.多进程方案(创建新的进程就需要申请更多的资源)2.使用多线程(资源开销小)

当引入的线程到达一定数量后在尝试继续引入新的线程无法提升,当线程数量太多的时候,线程之间就会相互竞争CPU的资源(CPU核心数有限)非但不会提高效率,反而增加调度开销

总结

1.线程也不是越多越好,要能够合适,如果线程太多了,调度开销就可能非常明显

2.多线程的线程之间,可能会打架,当线程之间起了冲突,会导致代码中出现一些逻辑错误(线程安全问题)

3.资源共享,若一个线程抛出异常,并且没有处理好,可能导致整个线程被终止

4.进程是包含线程的,线程是轻量级进程

5.每个线程,也是一个独立的执行流,可以执行一些代码,并且单独的参与到CPU调度中(状态,上下文,优先级,记账信息,每个线程都有自己的一份)

6.每个进程,有自己的资源,进程中的线程共用这一份资源(内存空间和文件描述符表)

即进程是资源分配的基本单位,线程是调度执行的基本单位

三.多线程编程

Thread类

在java中不推荐多进程进行并发编程,很多和多进程编程相关的api,在java标准库中都没有提供;

多线程并发编程系统提供了编程的api,java标准库把这些api封装了在代码中就可以使用

java提供的api,Thread这样的类:

1.Thread这个类可以直接使用,不需要导包-java-java标准库中有一个特殊的包(java.lang)

2.一个.java文件中,只能有一个public的类,这个类如果没有public包作用就只能在当前包里被其他类使用

一个进程中,至少会有一个线程,这个进程中的第一个线程也就称为"主线程"

此处的run不需要手动调用,会在线程创建好之后,被jvm自动调用执行(类似于main方法-主线程的入口方法)-是一个java进程(程序)的入口方法-回调函数

回调函数是编程中非常重要的概念

1.c-指针进阶=>函数指针

(1)实现转移表,降低圈复杂度(写个计算器)

(2)作为回调函数,(自己实现qsort)

2.java数据结构

优先级队列PriorityQueue-指定比较规则

Comparable(自己和别人比) 只有一种比较规则

Comparator(别人拿自己和别人比) 可以有多重规则

方法重写-override

本质:是让能够对现有的类进行扩展

一个线程执行代码,Thread类本身会带有run入口方法,但标准库自带的run不知道需求必须手动指定,就可以针对原有Thread进行扩展(把一些能够复用的进行重用,需要扩展的进行扩展)

Thread会有很多属性方法,大部分内容都复用即可,只是把需要扩展的这个进行扩展即可.

不写注释可以完成方法重写-是为了方便编译器,对代码进行自动检查(final,throws)

总代码图

 运行结果图

 此处没有手动调用run,但是run还是执行了,当引入多线程之后,代码中就可以同时具备多个执行流!!!一些逻辑

run是线程的入口,每个线程跑起来都会执行一些逻辑

四.操作系统

定义

最核心的功能模块(管理,管理硬件,给软件提供稳定的运行环境)

操作系统=内核空间(内核态)+用户空间(用户态)

内核空间:提供调用api,在内核中完成应用程序的操作;

用户空间:普通的应用程序

划分用户态和内核态:为了防止应用程序把硬件设备或者软件资源搞坏,系统封装api,这些api都是"合法"的操作,应用程序只能调用api,不至于对系统/硬件设备产生太大危害,若应用程序直接操作硬件极端情况代码出现bug会损害硬件

调度执行

每个线程都是一个独立的执行流,每个线程都能够独立的去CPU上调度执行

当有多线程的时候,线程的执行先后顺序是不确定的:操作系统内核中有一个调度器模块--实现方式类似随机调度的效果

随机调度(抢占式执行):线程被调度到CPU上执行时机不确定;线程从CPU上下来给别人让位时机不确定

通过第三方工具直观了解线程情况:jdk中jconsole工具-分析java进程

其中JVM自带的线程要完成一些垃圾回收(gc自动释放内存),监控统计各种指标,把指标通过网络方式传送给其他程序

  • 38
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值