当前位置: 首页 > news >正文

并发编程---线程与进程

业务场景:小明去理发店理发。

小明去理发店理发,完成理发需要吹,剪,洗、理的过程。由这个场景我们引用进程和线程这两个

概念。

一.进程

1.什么是进程

进程是具有独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的独立单位。进程是可与其他程序并发执行的程序,在一个数据集合上的运行过程。它是系统进行资源分配和调度的一个独立单位。

大家打开windows的任务管理器就可以看到,系统运行的进程。

2.进程的几个概念

2.1 结构性

为了控制和管理进程,系统为每个进程设立一个**进程控制块\- PCB。

每个进程拥有一个控制块(PCB),这是进程存在的依据,用于描述和记录进程的动态变化过程,并使之能正确运行。

2.2 动态性

进程的实质是程序的一次执行过程,进程是动态产生,动态消亡的,进程在其生命周期内,在三种基本状态(产生、执行、消亡)之间转换。

进程是程序在处理机上的一次动态执行过程。它因创建而产生,由调度而执行,因得不到资源而暂停执行,最后因撤销而消亡。

2.3 异步性

由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进。

系统中的各进程以独立的、不可预知的速度向前推进。

2.4 并发性

任何进程都可以同其他进程一起向前推进。

多个进程实体可以同时存在于内存中,在一段时间内都得到运行,它们在执行时间上是重叠的。

2.5 独立性

进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。

进程是能独立运行的基本单位,也是系统进行资源分配和调度的独立单位。

二.线程

我们把理发这个进程分解为几个子任务(线程)如下:

1.线程的定义

 1.1 线程是程序执行的**最小单位\,而进程是操作系统分配资源的最小单位;

 1.2 一个进程由一个或多个线程组成,线程是一个进程中代码的**不同执行路线\;

 1.3 进程之间相互独立,但同一进程下的**各个线程之间共享程序的内存空间(包括代码段,数据     集,堆等)及一些进程级的资源(如打开文件和信号等),某进程内的线程在其他进程不可见;

 1.4 调度和切换:线程上下文切换比进程**上下文切换要快得多\;

2.线程和进程的区别

3.线程的切换方式

三.线程的生命周期

1.线程创建

1.1 继承Thread类

public class ThreadDemo extends Thread{public ThreadDemo(String name){setName(name);}public void run(){for (int i = 1;i <= 100;i++){System.out.println(getName() + ":" + i);if (i==5) throw new RuntimeException("死亡");}}public static void main(String[] args) throws InterruptedException {Thread t1 = new ThreadDemo("A");Thread t2 = new ThreadDemo("B");t2.start();//readyt1.start();//ready
//        Thread.sleep(100);
//        System.out.println("main");}
}

1.2 实现Runnable接口

/*** 实现Runnable接口*/
public class ThreadDemo02 implements Runnable{private String name;public ThreadDemo02(String name) {this.name = name;}@Overridepublic void run() {for (int i = 0;i < 10;i++){System.out.println(this.name + "---" + i);}}public static void main(String[] args) {Thread t1 = new Thread(new ThreadDemo02("A"));Thread t2 = new Thread(new ThreadDemo02("B"));t2.start();t1.start();}
}

1.3 实现Callable接口

public class ThreadDemo01 implements Callable<Integer> {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 1; i < 1000; i++) {sum += i;}return sum;
}
public static void main(String[] args) throws Exception {FutureTask<Integer> ft =new FutureTask<Integer>(new ThreadDemo01());ft.run();System.*out\*.println("s:" + ft.get());}
}

2.线程就绪

Thread t = new Thread( );
t.start( ); //启动线程(线程就绪)

3.线程运行

一旦CPU分配了运行时间,就调用线程的run( )方法。

4.线程阻塞

线程阻塞可以分为以下几种类型:

1‌‌.等待阻塞‌:线程调用wait()方法,进入等待状态,等待其他线程的通知或者中断。
‌‌2.同步阻塞‌:线程在获取对象锁时,如果该锁被其他线程占用,则进入同步阻塞状态。
‌‌3.睡眠阻塞‌:线程调用sleep()方法,进入睡眠状态,等待一定时间后自动唤醒。
‌‌4.IO阻塞‌:线程在执行IO操作时,如果IO操作没有完成,则进入IO阻塞状态。
‌5.其他阻塞‌:线程调用join()方法等待其他线程执行完毕,或者调用yield()方法主动让出CPU资源。

5.线程死亡

线程死亡是线程生命周期的一个重要阶段。线程在完成其任务后自动进入死亡状态。当一个线程完成其执行,或因未捕获的异常而退出时,该线程将进入死亡状态,此时线程的所有资源将被释放。

线程死亡的条件:
1.正常结束:线程执行完run()方法。
2.异常结束:在线程执行过程中出现未处理的异常。
3.被强制终止:其他线程调用stop()等方法。

四.守护线程与用户线程

1.用户线程User Thread(创建的线程)

不需要内核支持而在用户程序中实现的线程

用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。

2.守护线程Daemon Thread(守护最后一个用户线程才结束)

守护线程是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。

import java.text.SimpleDateFormat;
import java.util.Date;/*** 守护线程*/
public class ShouHuDemo {public static void main(String[] args) throws Exception{Thread t1 = new Thread(() -> {while (true){try {Date now = new Date();long s1 = now.getTime();SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd hh:mm:ss");Date parse = sdf.parse("24-09-15 17:15:00");System.out.println(sdf.format(now));long s2 = parse.getTime();System.out.println("s1:" + s1 + "s2:" + s2);if (s1 == s2){System.out.println("到点了!!!");}Thread.sleep(1000);} catch (Exception e) {throw new RuntimeException(e);}}});Thread t2 = new Thread(() -> {for (int i = 0;i < 100;i++){try {System.out.println("o" + i);Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.setDaemon(true);t1.start();t2.start();}
}

相关文章:

  • ARM点灯---看手册
  • 几种常见点云开源库——点云、网格数据结构转换
  • Python使用总结之py-docx将word文件中的图片保存,并将内容返回
  • 前端项目依赖包中的依赖包漏洞解决方案
  • Python的包管理工具pip安装
  • 不可思议的转折,这部韩剧在口碑上实现逆袭
  • 15.面试算法-树基础
  • 统信服务器操作系统进入【单用户模式】
  • TM-align结果的PDB ID和链ID
  • LeetCode - 850 矩形面积 II
  • 【Linux】Linux基本命令
  • 征程6 上基于 DEB 工具实现包管理
  • c# 三元表达式
  • 基于python深度学习遥感影像地物分类与目标识别、分割实践技术
  • 数据采集使用动态代理被拦截的原因是什么?
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 【前端学习】-粗谈选择器
  • 2017-09-12 前端日报
  • 30秒的PHP代码片段(1)数组 - Array
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • in typeof instanceof ===这些运算符有什么作用
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • JAVA之继承和多态
  • Linux中的硬链接与软链接
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Node + FFmpeg 实现Canvas动画导出视频
  • SQLServer之创建显式事务
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 理解在java “”i=i++;”所发生的事情
  • 数据科学 第 3 章 11 字符串处理
  • 《码出高效》学习笔记与书中错误记录
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • #Datawhale AI夏令营第4期#多模态大模型复盘
  • #NOIP 2014# day.2 T2 寻找道路
  • #vue3 实现前端下载excel文件模板功能
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • $.ajax,axios,fetch三种ajax请求的区别
  • (145)光线追踪距离场柔和阴影
  • (2015)JS ES6 必知的十个 特性
  • (k8s)Kubernetes本地存储接入
  • (ZT)一个美国文科博士的YardLife
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (六)Flink 窗口计算
  • (论文阅读40-45)图像描述1
  • (三)SvelteKit教程:layout 文件
  • (生成器)yield与(迭代器)generator
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (转) Android中ViewStub组件使用