java基础之对线程的理解

目录

 

程序、进程、线程

什么是进程?

什么是线程

线程与进程的区别?

二、多线程

实现多线程方式一:继承Thread类

实现多线程方式二:实现Runnable接口

实现多线程方式三: 实现Callable接口

​ 三种实现方式的对比

设置和获取线程名称

线程休眠

线程优先级

守护线程


 

程序、进程、线程

  • 程序:程序如果不运行,就是物理磁盘上的文件,是静态的,比如我们电脑上的360.

  • 进程:是正在运行的程序,程序运行会向操作系统申请资源,进程是资源分配的基本单元。相对于程序,是动态的,比如我们电脑上的360双击运行。

  • 线程:是进程中的一条执行路径,是CPU调度执行的基本单元,一个进程下有可能包含多个线程。比如360下可以同时运行木马查杀、电脑清理等。

be65980699594cacaf1b8d64b429524b.png

什么是进程?

进程是指在计算机中运行的程序的实例。它是操作系统进行资源分配和调度的基本单位。一个进程可以包含多个线程,每个线程都共享该进程的资源,如内存、文件和打开的网络连接等。每个进程都有自己的地址空间,即独立的内存区域。

什么是线程

线程是进程内的执行单元,也是cpu的最小执行单元。一个进程可以包含多个线程,每个线程执行不同的任务。线程共享进程的资源,包括内存、文件和打开的网络连接等。线程之间通过共享内存进行通信,因此比进程间通信更高效。由于线程共享同一进程的地址空间,所以多线程之间的切换更快。

例如:我们启动JVM运行一个Java程序,其实就是启动了一个 JVM 的进程。在JVM的进程中,又包含了main :主线程、Reference Handler:清理线程、Finalizer:线程(用于调用对象 的finalize()方法)等线程。

线程与进程的区别?

根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位;

资源开销:每个进程都有独立的代码副本和数据空间,进程之间的切换,资源开销较大;线程可以看做轻量级的进程,每个线程都有自己独立的运行栈和程序计数器,线程之间切换,资源开销小;

内存分配:同一进程内的所有线程共享本进程的内存空间和资源;进程之间的内存空间和资源相互独立;

影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响;一个线程崩溃,会导致整个进程退出。所以多进程要比多线程健壮;

执行过程:每个独立的进程有程序运行的入口和程序出口。但是线程不能独立执行,必须依存在应用程序(进程)中,由应用程序提供多个线程执行控制;

包含关系:一个进程内包含有多个线程,在执行过程,线程的执行不是线性串行的,而是多条线程并行共同完成;

 

并发和并行​:

​并行:在同一时刻,有多个线程在多个CPU上同时执行。

0f1cbea1282f44eda9cdf01c9f48bc83.png

并发:在同一时刻,有多个线程在单个CPU上交替执行。

7ba5bf445a954337990c85becc9a2048.png

二、多线程

实现多线程方式一:继承Thread类

667540048b014abaab9aea220dd8e878.png

实现步骤

  • 定义一个类MyThread继承Thread类

  • 在MyThread类中重写run()方法

  • 创建MyThread类的对象

  • 启动线程

public class MyThread extends Thread {@Overridepublic void run() {for(int i=0; i<100; i++) {System.out.println(i);}}
}
public class MyThreadDemo {public static void main(String[] args) {MyThread my1 = new MyThread();MyThread my2 = new MyThread();//        my1.run();
//        my2.run();//void start() 导致此线程开始执行; Java虚拟机调用此线程的run方法my1.start();my2.start();}
}
  • 为什么要重写run()方法?

    因为run()是用来封装被线程执行的代码

  • run()方法和start()方法的区别?

    run():封装线程执行的代码,直接调用,相当于普通方法的调用

    start():启动线程;然后由JVM调用此线程的run()方法

实现多线程方式二:实现Runnable接口

d8853927c9164af1b8afd61b7a7da6b7.png

  • 实现步骤

    • 定义一个类MyRunnable实现Runnable接口

    • 在MyRunnable类中重写run()方法

    • 创建MyRunnable类的对象

    • 创建Thread类的对象,把MyRunnable对象作为构造方法的参数

    • 启动线程

  • 代码演示

public class MyRunnable implements Runnable {@Overridepublic void run() {for(int i=0; i<100; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}
}
public class MyRunnableDemo {public static void main(String[] args) {//创建MyRunnable类的对象MyRunnable my = new MyRunnable();//创建Thread类的对象,把MyRunnable对象作为构造方法的参数//Thread(Runnable target)
//        Thread t1 = new Thread(my);
//        Thread t2 = new Thread(my);//Thread(Runnable target, String name)Thread t1 = new Thread(my,"坦克");Thread t2 = new Thread(my,"飞机");//启动线程t1.start();t2.start();}
}

实现多线程方式三: 实现Callable接口

88a7be2aa8b64900b9753244efc4239a.png

public class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {for (int i = 0; i < 100; i++) {System.out.println("跟女孩表白" + i);}//返回值就表示线程运行完毕之后的结果return "答应";}
}
public class Demo {public static void main(String[] args) throws ExecutionException, InterruptedException {//线程开启之后需要执行里面的call方法MyCallable mc = new MyCallable();//Thread t1 = new Thread(mc);//可以获取线程执行完毕之后的结果.也可以作为参数传递给Thread对象FutureTask<String> ft = new FutureTask<>(mc);//创建线程对象Thread t1 = new Thread(ft);//String s = ft.get();//开启线程t1.start();//获取执行之后的结果String s = ft.get();System.out.println(s);}
}

​ 三种实现方式的对比

  • 实现Runnable、Callable接口

    • 好处: 扩展性强,实现该接口的同时还可以继承其他的类

    • 缺点: 编程相对复杂,不能直接使用Thread类中的方法

  • 继承Thread类

    • 好处: 编程比较简单,可以直接使用Thread类中的方法

    • 缺点: 可以扩展性较差,不能再继承其他的类

设置和获取线程名称

9c8a5c2d7f424d4d9ce3f517e132bf8d.png

public class MyThread extends Thread {public MyThread() {}public MyThread(String name) {super(name);}@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(getName()+":"+i);}}
}
public class MyThreadDemo {public static void main(String[] args) {MyThread my1 = new MyThread();MyThread my2 = new MyThread();//void setName(String name):将此线程的名称更改为等于参数 namemy1.setName("高铁");my2.setName("飞机");//Thread(String name)MyThread my1 = new MyThread("高铁");MyThread my2 = new MyThread("飞机");my1.start();my2.start();//static Thread currentThread() 返回对当前正在执行的线程对象的引用System.out.println(Thread.currentThread().getName());}
}

线程休眠

4f0c8926705441c0b24162eb076c5d4f.png

public class MyRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 100; i++) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "---" + i);}}
}
public class Demo {public static void main(String[] args) throws InterruptedException {/*System.out.println("睡觉前");Thread.sleep(3000);System.out.println("睡醒了");*/MyRunnable mr = new MyRunnable();Thread t1 = new Thread(mr);Thread t2 = new Thread(mr);t1.start();t2.start();}
}

线程优先级

线程调度

  • 两种调度方式

    • 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片

    • 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些

  • Java使用的是抢占式调度模型

  • 随机性

    假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的

f4d9748ff459480090daeae1fe86a939.png

 

public class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + "---" + i);}return "线程执行完毕了";}
}
public class Demo {public static void main(String[] args) {//优先级: 1 - 10 默认值:5MyCallable mc = new MyCallable();FutureTask<String> ft = new FutureTask<>(mc);Thread t1 = new Thread(ft);t1.setName("飞机");t1.setPriority(10);//System.out.println(t1.getPriority());//5t1.start();MyCallable mc2 = new MyCallable();FutureTask<String> ft2 = new FutureTask<>(mc2);Thread t2 = new Thread(ft2);t2.setName("坦克");t2.setPriority(1);//System.out.println(t2.getPriority());//5t2.start();}
}

守护线程

  • 用户线程和守护线程

    我们自己写的线程就叫做用户线程,当给这个线程通过setDaemon设置成true之后,用户线程就变成了守护线程。

    守护线程的特点: 当用户线程都执行完成之后,守护线程就没有执行的必要了。

  • 相关方法

3a8e9a09b8584e4cab02abaf6d308922.png

public class MyThread1 extends Thread {@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(getName() + "---" + i);}}
}
public class MyThread2 extends Thread {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(getName() + "---" + i);}}
}
public class Demo {public static void main(String[] args) {MyThread1 t1 = new MyThread1();MyThread2 t2 = new MyThread2();t1.setName("女神");t2.setName("备胎");//把第二个线程设置为守护线程//当普通线程执行完之后,那么守护线程也没有继续运行下去的必要了.t2.setDaemon(true);t1.start();t2.start();}
}

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/838822.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【WEEK12】 【DAY3】整合MyBatis框架【中文版】

2024.5.15 Wednesday 目录 13.整合MyBatis框架13.1.整合测试13.1.1.新建springboot-05-mybatis项目13.1.2.导入MyBatis需要的依赖13.1.3.配置数据库连接信息13.1.3.1.修改application.properties13.1.3.2.修改Springboot05MybatisApplicationTests.java并测试 13.1.4.新建pojo文…

InnoDB 事务处理机制

文章目录 前言1. 事务处理挑战1.1 事务机制处理的问题1.2 并发事务带来的问题 2. InnodDB 和 ACID 模型2.1 Innodb Buffer Pool2.2 Redo log2.3 Undo log2.4 应用案例 3. 隔离级别和锁机制3.1 事务隔离级别3.1.1 READ UNCOMMITTED3.1.2 READ COMMITTED3.1.3 REPEATABLE READ3.1…

SpringBoot应用

文章目录 第一章、SpringBoot基础内容一、Spring和SpringBoot1、Spring介绍2、SpringBoot介绍 二、SpringBoot2入门操作1、在线构建2、idea构建 三、浅谈自动装配的原理 第二章、SpringBoot核心功能一、配置文件1、配置文件介绍2、语法规则3、数据类型4、案例使用 二、WEB开发1…

如何管理测试用例?测试用例有什么管理工具?YesDev

3.1 测试用例 测试用例(Test Case) 是指对一项特定的软件产品进行测试任务的描述&#xff0c;体现测试方案、方法、技术和策略。其内容包括测试目标、测试环境、输入数据、测试步骤、预期结果等。简单地认为&#xff0c;测试用例是为某个特殊目标而编制的一组测试输入、执行条…

CPT7数据保存详细步骤

一、连接设备、打开NovAtelConnect 软件 (1)点击1,并在2中输入如下命令: LOG RANGEB ONTIME 1 // 输出原始数据记录在板卡LOG RAWEPHEMB ONTIME 1 // 输出 GPS 原始星历记录在板卡LOG bdsephemerisb ONTIME 1 // 输出

在澳门写代码;技术入股2次融资被踢;现在只想做独立开发

本期我们邀请的程序员是Albert&#xff0c;先后在广州、澳门、珠海、香港工作过&#xff0c;打工上班、合伙创业、远程工作、独立开发&#xff0c;工作经历丰富&#xff0c;如果你想知道哪些程序员踩过的坑&#xff0c;请别错过他的故事。 广州&#xff1a;第一份工作2000块一…

C++ 结构体内存对齐

定义了两个结构体 typedef struct Cmd {uint8_t ua;uint8_t ub;uint8_t uc;uint32_t ue; } Cmd_t;typedef struct Cmd_tag {uint8_t value;uint8_t data[1]; // 将 data 定义为指向 Cmd_t 结构体的指针 } tag_t;在实际使用中&#xff0c;看见前人的代码是&#xff0c;new 一块内…

MySQL第三次作业--DML语句(INSERT)

目录 一、在数据库中创建一个表student&#xff0c;用于存储学生信息 二、向student表中添加一条新记录&#xff0c;记录中id字段的值为1&#xff0c;name字段的值为"monkey"&#xff0c;grade字段的值为98.5 三、向student表中添加多条新记录&#xff1a; 2,&qu…

详解动态规划之01背包问题及其空间压缩(图文并茂+例题讲解)

1. 动态规划问题的本质 记忆化地暴力搜索所有可能性来得到问题的解 我们常常会遇到一些问题&#xff0c;需要我们在n次操作&#xff0c;且每次操作有k种选择时&#xff0c;求出最终需要的最小或最大代价。处理类似的问题&#xff0c;我们一般需要遍历所有的可能性(相当于走一遍…

SpringMVC核心组件之HandlerMapping详解

文章目录 前言一、AbstractHandlerMapping抽象类initApplicationContextgetHandler 二、MatchableHandlerMapping类二、AbstractUrlHandlerMapping类 前言 当一个web请求到来时&#xff0c;DispatcherServlet负责接收请求并响应结果。DispatcherServlet首先需要找到当前请求对…

普通人也能创业!轻资产短视频带货项目,引领普通人实现创业梦想

在这个信息爆炸的时代&#xff0c;创业似乎成为了越来越多人的梦想。然而&#xff0c;传统的创业模式 keJ0277 往往伴随着高昂的资金投入和复杂的管理流程&#xff0c;让许多普通人望而却步。然而&#xff0c;现在有一种轻资产短视频带货项目正在悄然兴起&#xff0c;它以其低…

2024做安全测试必须要知道的几种方法!

前言 安全性测试(Security Testing)是指有关验证应用程序的安全等级和识别潜在安全性缺陷的过程&#xff0c;其主要目的是查找软件自身程序设计中存在的安全隐患&#xff0c;并检查应用程序对非法侵入的防范能力&#xff0c;安全指标不同&#xff0c;测试策略也不同。 但安全…

『Apisix安全篇』快速掌握APISIX Basic-Auth插件高效使用

&#x1f4e3;读完这篇文章里你能收获到 &#x1f468;‍&#x1f4bb; 学习如何快速安装并配置APISIX Basic-Auth插件&#xff0c;为您的API安全保驾护航。&#x1f6e0;️ 文章详细介绍了如何创建带有basic-auth配置的Consumer&#xff0c;以及如何在Route中启用该插件。&am…

微信自主创建表单投票小程序源码系统 带充值刷礼物功能 附带源代码以及完整的安装部署教程

系统概述 本小程序实现的核心功能包括&#xff1a;用户注册登录、表单提交投票、查看投票结果、在线充值以及赠送礼物等。其中&#xff0c;投票表单可以根据实际需求进行自定义设置&#xff0c;满足不同类型的调查或评选活动。同时&#xff0c;通过引入第三方支付接口&#xf…

Django Celery 的配置及使用---最详细教程

Django Celery 的配置及使用 Redis提供队列消息功能 一、安装redis 系统版本&#xff1a;Ubuntu 20.041、获取最新软件包 sudo apt update sudo apt install redis-server2、安装完成后&#xff0c;Redis服务器会自动启动。查看redis是否启动成功 sudo systemctl status …

LLM大模型多模态面试题(二)

1. 介绍transformer算法 Transformer本身是一个典型的encoder-decoder模型&#xff0c;Encoder端和Decoder端均有6个Block&#xff0c;Encoder端的Block包括两个模块&#xff0c;多头self-attention模块以及一个前馈神经网络模块&#xff1b;Decoder端的Block包括三个模块&…

uniapp 实现下拉刷新 下滑更新

效果图 在app或者小程序中向下滑动 会出现刷新数据 ,而上拉到底 需要更新数据 功能实现 主要俩种方式 依赖生命周期 在page.json中开启 page.json "style" : {"navigationBarTitleText" : "小小练习","backgroundTextStyle": &qu…

狙击策略专用术语以及含义,WeTrade3秒讲解

想必各位交易高手对狙击策略不会陌生吧!但你想必不知道狙击策略的开发者为了推广狙击策略&#xff0c;在狙击策略基础的经典技术分析理论引入了自己的术语。今天WeTrade众汇和各位投资者继续了解狙击策略专用术语以及含义。 一.BL 银行级别(BL)是前一日线收盘的级别。时间是格…

微信小程序开发中怎么配置SSL证书?

在微信小程序开发中&#xff0c;配置SSL证书主要用于实现HTTPS请求&#xff0c;以保证数据传输的安全性。以下是配置SSL证书的基本步骤&#xff1a; 一、获取SSL证书 首先&#xff0c;你需要获取一个有效的SSL证书。SSL证书可以被广泛信任的证书颁发机构申请&#xff0c;如Jo…

rocketmq的顺序消息开发注意事项

1. 参考消息重试&#xff0c;要对 MaxReconsumeTimes进行设置。之前就是因为没有进行设置&#xff0c;导致了队头阻塞问题。 rokcetmq和kafka一样&#xff0c;当顺序消息写入的多个队列中后&#xff0c;如果是顺序消息&#xff0c;当前的队列的队头一直消费失败的时候&#x…