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

JAVA进程和线程

 哈喽~大家好呀,这篇来看看JAVA进程和线程。

 🥇个人主页:个人主页​​​​​                       

🥈 系列专栏:【日常学习上的分享】

🥉与这篇相关的文章:                      

Redis快速入门及在Java中使用RedisRedis快速入门及在Java中使用Redis_程序猿追的博客-CSDN博客
为什么不推荐使用Lombok?@Data不香吗?为什么不推荐使用Lombok?@Data不香吗?-CSDN博客
Mybatis报错: Parameter ‘XXX‘ not found. Available parameters are [arg1, arg0, param1, param2]解决方案及问题原因Mybatis报错: Parameter ‘XXX‘ not found. Available parameters are [arg1, arg0, param1, param2]解决方案及问题原因-CSDN博客

目录

一、前言

1、进程和线程概念

2、线程的优先级

二、Thread 类

三、Runnable 接口

四、线程同步

1、synchronized 

 2、使用方式

五、死锁问题

六、生产者与消费者实战案例

七、图书推荐


一、前言

1、进程和线程概念

什么是进程
进程就是正在运行的程序,它是系统资源调度的独立单位,并且一个进程可以执行多个任务,而线程就是程序执行的任务,它是程序使用CPU的基本单位,因此也可以说线程是依赖于进程的。像比如任务管理器里面的运行任务就是线程。

单进程与多进程的概述
单进程的计算机一次只能做一件事情,而多进程的计算机可以做到一次做不同的事情,比如一边听音乐,一边听打游戏,这两件事情虽然感觉起来是在同时一起进行的,但其实是CPU在做着程序间的高效切换,这才让我们觉得是同时进行的。

什么是线程

线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位

一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。

线程的状态

线程的生命周期

  • 新建状态:

    使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。

  • 就绪状态:

    当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。

  • 运行状态:

    如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。

  • 阻塞状态:

    如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:

    • 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。

    • 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。

    • 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。

  • 死亡状态:

    一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

2、线程的优先级

每一个 Java 线程都有一个优先级,这样有助于操作系统确定线程的调度顺序。

Java 线程的优先级是一个整数,其取值范围是 1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )。

默认情况下,每一个线程都会分配一个优先级 NORM_PRIORITY(5)。

二、Thread 类

使用 Thread 来创建线程,类继承与 Thread 类。继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。

格式

package com.zte.thread;public class ThreadA extends Thread{// run() 方法线程执行的第一步,同main方法@Overridepublic void run() {}}

示例

public class ThreadA extends Thread{// run() 方法线程执行的第一步,同main方法@Overridepublic void run() {for (int i = 1; i <= 200; i++) {System.out.println("i : " + i);}}}public class ThreadB extends  Thread{@Overridepublic void run() {for (int i = 0; i < 200; i++) {System.out.println("j :" + i);}}
}public class Text {public static void main(String[] args){ThreadA a = new ThreadA();ThreadB b = new ThreadB();a.start();b.start();}
}

运行结果

 打印太多了,我们只看关键的一部分,很明显多个线程明显在抢占资源

扩:

这里我们看下 start()  与 run()  的区别

start() :

它的作用是启动一个新线程。
通过start()方法来启动的新线程,处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行相应线程的run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即终止。start()不能被重复调用。用start方法来启动线程,真正实现了多线程运行,即无需等待某个线程的run方法体代码执行完毕就直接继续执行下面的代码。这里无需等待run方法执行完毕,即可继续执行下面的代码,即进行了线程切换。
 

run() :

run()就和普通的成员方法一样,可以被重复调用。
如果直接调用run方法,并不会启动新线程!程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到多线程的目的。
总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里
 

简单来说就是 start() 可以创建多个线程,不能重复调用,而 run() 创建单个线程,能重复调用。

三、Runnable 接口

创建一个线程,最简单的方法是创建一个实现 Runnable 接口的类,使用 run 来调用线程

示例

public class ThreadA implements Runnable{// run() 方法线程执行的第一步,同main方法@Overridepublic void run() {for (int i = 1; i <= 200; i++) {try {Thread.sleep(1000); // 让线程睡眠一会} catch (InterruptedException e) {e.printStackTrace();}System.out.println("i : " + i);}}}public class ThreadB implements Runnable{@Overridepublic void run() {for (int i = 0; i < 200; i++) {try {Thread.sleep(1000); // 让线程睡眠一会} catch (InterruptedException e) {e.printStackTrace();}System.out.println("j :" + i);}}
}public class Text {public static void main(String[] args){ThreadA a = new ThreadA();ThreadB b = new ThreadB();a.run();b.run();}
}

扩:

1、当我们使用了 Runnable 实例化对象就不能调用 start 方法了,只能用 run 了。

2、sleep 的意思是强制当前正在执行的线程休眠(暂停执行),例如:【Thread.sleep(long millis)】当线程睡眠时它不会在苏醒之前返回到可运行状态;当睡眠时间到期后才会返回到可运行状态。里面放的毫秒值。

四、线程同步

1、synchronized 

什么是 synchronized ?

答:synchornized 是 Java 中的一个关键字,解决的是多个线程之间访问资源的同步性,synchronized 关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。

在上面我们遇到了线程抢占的问题,而 synchronized 就是来解决这问题的。

应用场景

 2、使用方式

修饰实例方法:作用于当前对象实例加锁,进入同步代码前要获得 当前对象实例的锁

synchronized void method() {//业务代码
}

 修饰静态方法: 也就是给当前类加锁,会作用于类的所有对象实例 ,进入同步代码前要获得 当前 class 的锁。

synchronized static void method() {//业务代码
}

修饰代码块 :指定加锁对象,对给定对象/类加锁。synchronized(this|object) 表示进入同步代码库前要获得给定对象的锁。synchronized(类.class) 表示进入同步代码前要获得 当前 class 的锁

synchronized(this) {//业务代码
}

案例(银行存钱与取钱)

分析:银行比作容器,取钱与存放是两个进程,并且不能同时进行。

public class Account extends Thread{private int balance = 1000;Object o = new Object(); // 或者用 thispublic void withdraw(int n){synchronized (o){balance -= n;System.out.println("取了 : " + n + "  还剩 : " + balance);}}public void deptdraw(int n){synchronized (o){balance += n;System.out.println("存了 : " + n + "  还剩 : " + balance);}}}public class PersonA extends Thread{private Account account;public Account getAccount() {return account;}public void setAccount(Account account) {this.account = account;}@Overridepublic void run() {for (int i = 0; i < 3; i++) {account.withdraw(100);}}}public class PersonB extends Thread{private Account account;public Account getAccount() {return account;}public void setAccount(Account account) {this.account = account;}@Overridepublic void run() {for (int i = 0; i < 3; i++) {account.deptdraw(100);}}}public class Text {public static void main(String[] args){Account acc = new Account();PersonA a = new PersonA();PersonB b = new PersonB();a.setAccount(acc);b.setAccount(acc);b.start();a.start();}
}

运行结果

五、死锁问题

什么是死锁?

答:线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁。
 

简单来讲就是,t1 线程在等 t2 线程,t2 线程也在等 t1 线程,这就陷入到了死循环了,这就叫死锁。

示例

public class AddAndSub {public Object objectA = new Object();public Object objectB = new Object();public void add(){synchronized (objectA){System.out.println(Thread.currentThread().getName() + "我获取到了a");try {objectA.wait();System.out.println("我等到了");} catch (InterruptedException e) {e.printStackTrace();}synchronized (objectB){System.out.println(Thread.currentThread().getName() + "我获取到了b");}System.out.println(Thread.currentThread().getName() + "我失去了b");}System.out.println(Thread.currentThread().getName() + "我失去了a");}public void sub(){synchronized (objectB){System.out.println(Thread.currentThread().getName() + "我获取到了b");try {Thread.sleep(1000);
//                System.out.println("我等到了");} catch (InterruptedException e) {e.printStackTrace();}//            synchronized (objectB){System.out.println(Thread.currentThread().getName() + "我获取到了a");
//                objectA.notify();
//            }System.out.println(Thread.currentThread().getName() + "我失去了a");}System.out.println(Thread.currentThread().getName() + "我失去了b");}}public class TB extends Thread{public AddAndSub addAndSub;@Overridepublic void run() {addAndSub.sub();}
}public class TA extends Thread{public AddAndSub addAndSub;@Overridepublic void run() {addAndSub.add();}
}public class Text {public static void main(String[] args){AddAndSub d = new AddAndSub();TA a = new TA();TB b = new TB();a.setName("线程A");b.setName("线程B");a.addAndSub = d;b.addAndSub = d;a.start();b.start();a.setPriority(Thread.MAX_PRIORITY);}
}

 死锁了,进程 A 一直在等进程 B ,但 B 一直在等 A。

六、生产者与消费者实战案例

分析:有一个箱子,生产者生产牛奶,放入到箱子里面,消费者在箱子里面拿牛奶

示例

public class Box {private int milk = 0;private boolean state = false;public synchronized void put(int milk){if (state){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}this.milk = milk;System.out.println("放了" + this.milk + "瓶奶");state = true;notifyAll();}public synchronized void get(){if (!state){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}
//        this.milk = milk;System.out.println("拿走了" + this.milk + "瓶奶");state = false;notifyAll();}}public class shengchan implements Runnable {private Box b;public shengchan(Box box) {this.b = box;}@Overridepublic void run() {for (int i = 0; i < 10; i++) {b.put(i + 1);}}}public class xiaofei implements Runnable {private Box b;public xiaofei(Box box) {this.b = box;}@Overridepublic void run() {while (true) {b.get();}}
}public class Main {public static void main(String[] args) {Box box = new Box();shengchan shengchan = new shengchan(box);xiaofei xiaofei = new xiaofei(box);Thread threadA = new Thread(shengchan);Thread threadB = new Thread(xiaofei);threadA.start();threadB.start();}}

运行结果

七、图书推荐

内容简介

本书从 MATLAB 基础语法讲起,介绍了基于 MATLAB 函数的科学计算问题求解方法,实现了大量科学计算算法。

本书分为三大部分。第 1 章和第 2 章为 MATLAB 的基础知识,对全书用到的 MATLAB 基础进行了简单介绍。第 3 ~ 12 章为本书的核心部分,包括线性方程组求解、非线性方程求解、数值优化、数据插值、数据拟合与回归分析、数值积分、常微分方程求解、偏微分方程求解、概率统计计算及图像处理与信号处理等内容。第 13 ~ 15 章为实战部分,以实际生活中的数学问题为例,将前文介绍的各类科学计算算法应用其中。

本书内容全面、通俗易懂,适合有一定 MATLAB 基础、想要进行进阶学习的读者。

购买链接

相关文章:

JAVA进程和线程

哈喽~大家好呀&#xff0c;这篇来看看JAVA进程和线程。 &#x1f947;个人主页&#xff1a;个人主页​​​​​ &#x1f948; 系列专栏&#xff1a;【日常学习上的分享】 &#x1f949;与这篇相关的文章&#xff1a; Redis快速入…...

3.2-Docker Image概述

...

JS自定义深浅度克隆

function deepClone(obj, cache new WeakMap()) {if (typeof obj ! object) return obj //普通类型&#xff0c;直接返回if (obj null) return objif (cache.get(obj)) return cache.get(obj)//防止循环引用&#xff0c;程序进入死循环if (obj instanceof Date) return new D…...

MySQL之表的约束

目录 表的约束1.空属性2.默认值3.列描述4.zerofill5.主键6.自增长7.唯一键8.外键 表的约束 真正约束字段的是数据类型&#xff0c;数据类型规定了数据的用法、范围…假如我们没有按照其规定的约束&#xff0c;那么数据将插入不成功但是数据类型约束很单一&#xff0c;需要有一…...

Go基础——接口、并发

1、接口 Go 语言提供了另外一种数据类型即接口&#xff0c;它把所有的具有共性的方法定义在一起&#xff0c;任何其他类型只要实现了这些方法就是实现了这个接口。接口可以让不同的类型绑定到一组公共的方法上&#xff0c;从而实现多态和灵活的设计。Go 语言中的接口是隐式实现…...

zookeeper本地部署和集群搭建

zookeeper&#xff08;动物园管理员&#xff09;是一个广泛应用于分布式服务提供协调服务Apache的开源框架 Zookeeper从设计模式角度来理解&#xff1a;是一个基于观察者模式设计的分布式服务管理框架&#xff0c;它 负责存储和管理大家都关心的数据 &#xff0c;然 后 接受观察…...

优橙内推甘肃专场——5G网络优化(中高级)工程师

内推公司1&#xff1a;上海井胜通讯技术有限公司 内推公司2&#xff1a;西安长河通讯有限责任公司 内推公司3&#xff1a;沈阳电信工程局 上海井胜通讯技术有限公司 公司成立于2002年&#xff0c;是一家专业移动通信技术服务公司。2008年之前是香港一家大型流动通讯运营公司…...

crontab 定时任务

1.查看 crond 是否开启 systemctl status crond 2.设置 crontab 定时任务 基本语法 #基本语法 crontab [选项] 查看定时任务 #查看定时任务 crontab -l 编辑定时任务 #编辑定时任务 crontab -e 案例实操 */1 * * * * echo "hello,world" >> /root/hel…...

【入门Flink】- 03Flink部署

集群角色 Flik提交作业和执行任务&#xff0c;需要几个关键组件&#xff1a; 客户端(Client)&#xff1a;代码由客户端获取并做转换&#xff0c;之后提交给JobManger JobManager&#xff1a;就是Fink集群里的“管事人”&#xff0c;对作业进行中央调度管理&#xff1b;而它获…...

DockerFile常用保留字指令及知识点合集

目录 DockerFile加深理解&#xff1a; DockerFile常用保留字指令 保留字&#xff1a; RUN&#xff1a;容器构建时需要运行的命令 COPY&#xff1a;类似ADD&#xff0c;拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 …...

怎么批量删除文件名中的空格?

怎么批量删除文件名中的空格&#xff1f;当我们整理文件的时候发现文件名里面有一些空格&#xff0c;如果空格较多&#xff0c;可能会造成文件名特别的长&#xff0c;我们一般会随手对文件进行重命名&#xff0c;然后将文件名中的空格删除掉&#xff0c;这项操作非常的简单方便…...

回顾十大数据恢复软件,帮助用于恢复丢失的文件!

您是否因丢失计算机上的重要文件而感到恐慌&#xff1f;你不是一个人&#xff01;数据丢失是许多人面临的严重问题&#xff0c;但幸运的是&#xff0c;有许多解决方案可以恢复数据。 在本文中&#xff0c;我将回顾十大数据恢复软件&#xff0c;以帮助您恢复丢失的文件&#xf…...

【Linux】多路IO复用技术②——poll详解如何使用poll模型实现简易的一对多服务器(附图解与代码实现)

在阅读本篇博客之前&#xff0c;建议大家先去看一下我之前写的这篇博客&#xff0c;否则你很可能会一头雾水 【Linux】多路IO复用技术①——select详解&如何使用select模型在本地主机实现简易的一对多服务器&#xff08;附图解与代码实现&#xff09;http://t.csdnimg.cn/…...

CSS 滚动捕获 Scroll Snap

CSS 滚动捕获 Scroll Snap CSS 滚动捕获允许开发者通过声明一些位置(或叫作捕获位置)来创建精准控制的滚动体验. 通常来说轮播图就是这种体验的例子, 在轮播图中, 用户只能停在图 A 或者图 B, 而不能停在 A 和 B 的中间. 比如平时用淘宝或小红书, 当你上滑到下一个推荐内容时…...

【带头学C++】----- 三、指针章 ---- 3.9 数组作为函数的参数

当数组作为函数参数时&#xff0c;有几种常见的方式可以传递数组给函数&#xff1a; 数组作为指针传递&#xff1a; 数组名在函数调用时会自动转换为指向数组第一个元素的指针。通过指针可以访问数组元素&#xff0c;但无法获取数组的大小。在函数中修改指针指向的值会影响原始…...

完美处理 Android App 的 apk 输出路径与文件名

实现代码 buildTypes {// ...applicationVariants.all {variant ->variant.outputs.all {Calendar calendar Calendar.getInstance(Locale.CHINA);def buildDate String.format(Locale.CHINA, "%04d%02d%02d", calendar.get(Calendar.YEAR), calendar.get(Cale…...

【技术干货】开源库 Com.Gitusme.Net.Extensiones.Core 的使用

目录 1、项目介绍 2、为项目添加依赖 3、代码中导入命名空间 4、代码中使用 示例 1&#xff1a;string转换 示例 2&#xff1a;object转换 1、项目介绍 Com.Gitusme.Net.Extensiones.Core是一个.Net扩展库。当前最新版本1.0.4&#xff0c;提供了常见类型转换&#xff0c…...

大厂面试题-b树和b+树的理解

为了更清晰的解答这个问题&#xff0c;从三个方面来回答&#xff1a; a.了解二叉树、AVL树、B树的概念 b.B树和B树的应用场景 1.B树是一种多路平衡查找树&#xff0c;为了更形象的理解&#xff0c;我们来看这张图。 二叉树&#xff0c;每个节点支持两个分支的树结构&#xff…...

NeRF-SLAM部署运行(3060Ti)

记录在部署运行期间遇到的一些问题&#xff0c;分享给大家~ 一、环境 RTX 3060 Ti、8G显存、Ubuntu18.04 二、部署 1. 下载代码 git clone https://github.com/jrpowers/NeRF-SLAM.git --recurse-submodules git submodule update --init --recursive cd thirdparty/insta…...

零基础编程入门教程软件推荐,零基础编程自学

零基础编程入门教程软件推荐&#xff0c;零基础编程自学 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#xff0c;而且可以开发大型的软件&#xff0c;象如图这个实例就是用…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...