Java之多线程初阶

news2024/11/18 19:27:04

目录

一.进程和线程

1.什么是进程

2.并发,并行和串行

3.线程和多线程

4.进程和线程的区别(重点)

5.多线程的优点

6.多线程的缺点

二.线程的创建

1.继承Thread类

2.实现Runnable接口重写run()方法

3.通过匿名内部类的方式创建Thread和实现Runnable

4.通过Lambda表达式来实现一个线程

三.查看Java中创建线程的状态

1.直接到JDK中寻找jconsole.exe文件

 2.命令行中直接搜索jconsole


一.进程和线程

1.什么是进程

在计算机中,进程是指正在运行的程序的实例。进程是操作系统进行资源分配和调度的基本单位。

每个进程都有其独立的内存空间和数据栈,使得它们之间相互隔离,避免了不同进程之间的数据干扰。操作系统通过分配资源,管理进程间的调度,使得进程可以有序、并发地运行。同时,进程之间也可以通过各种通信机制进行数据传输和共享,这些通信机制可以使不同进程之间协同工作,共同完成任务。

进程可以处于不同的状态,例如运行、就绪、堵塞等,进程状态的变化可以由内部事件和外部事件引起。内部事件包括程序的运行、资源的申请和释放等,而外部事件则包括输入/输出请求、信号等。操作系统会根据不同的事件,将进程切换到不同的状态,以便对进程进行管理和调度。

2.并发,并行和串行

串行(Serial)指的是一个任务或进程按顺序逐个完成,一个任务完成后,另一个任务才开始执行。例如,一个计算机需要处理多个任务,这个时候串行是一个任务执行完毕之后,才能处理下一个任务.

并发(Concurrent)指的是多个任务在相同时间段内交替执行。在单处理器系统中,实现并发需要快速地在多个任务之间切换。例如,一个计算机需要同时运行多个应用程序,每个应用程序都有一个单独的进程,操作系统需要在这些进程之间快速地切换。

并行(Parallel)指的是多个任务同时执行,每个任务在不同的处理器独立运行。并行需要多个处理器或多个计算机来同时执行不同的任务。例如,一个大型计算任务被分成多个子任务,每个子任务分配到不同的处理器或计算机上执行。

在计算机领域中,并行和并发的概念通常被用来提高系统性能和响应能力。通过同时执行多个任务或进程,可以最大限度地利用计算机系统的资源。而串行则在某些情况下更为简单和可控,例如在单线程程序或少量任务的情况下。

再来举一个生活中的例子,当我们在吃饭(任务A)的时候,这个时候电话铃响了.

①串行:我们需要吃完饭之后,才能进行接电话(任务B).

②并发:我们一会去接电话,一会吃饭,同时只进行一个任务,但是可以快速的切换这两个任务,一会进行任务A,一会进行任务B.

③并行:我们一边吃饭,一边接电话,任务A和任务B同时进行

3.线程和多线程

多线程是指在一个进程中同时运行多个线程的技术。线程是指一个程序内部的执行路径,每个线程都拥有自己的堆栈和寄存器,并且能够访问共享内存中的变量和对象。与进程相比,线程是轻量级的,一个进程可以同时拥有多个线程

为什么要存在线程呢?

根据上面定义我们可以知道线程是轻量级的.多线程的开辟比多进程的开辟更能解决资源的消耗问题.下面是进程开辟时需要进行的操作:

这样显然是十分消耗内存的,因此便有了线程

创建线程只关注要处理的任务,使用的是进程创建时申请到的所有资源

案例:创建工厂

张三需要创建工厂生产生活用品,他需要在厂区申请一块地皮创建工厂(CPU给进程分配资源),工厂就相当于一个线程,这个厂区还有其他的工厂,别人的工厂(其他的线程),他们之前生产的东西之间互不影响.然后张三的工厂里面有需要的生产线(线程),负责生产不同的产品(也可能不同的生产线生产相同的产品),各个生产线之间可以相互影响(线程可以相互影响).申请地皮创建工厂的花费是很大的,需要建设厂房,购买基础设施等等(进程的创建的代价很大),而一条生产线可以相对容易的创建(线程的创建较容易).因此张三需要夸大生产,可以优先考虑创建生产线(进程)

4.进程和线程的区别(重点)

  1. 对于进程而言,至少有一条线程(主线程).
  2. 进程是申请系统资源的最小单位.
  3. 线程是CPU调度的最小单位.
  4. 进程之间互不影响,线程之间可以互相影响.

5.多线程的优点

  1. 充分利用CPU的资源
  2. 利用轻量级线程的特性减少系统的开销  

    a.线程创建的效率比进程高                                                                                                     b.线程销毁的效率比进程高                                                                                                     c.线程调度的效率比进程高

6.多线程的缺点

多线程也可以存在一些问题

这里我们拿小呆呆吃100个棒棒糖为例

如何我们使用多进程的话,需要的是两个桌子,每个桌子各放50个棒棒糖,然后进行吃

 

如果采用多线程的模式化,只需要在一个桌子上多增加几个小呆呆进行吃

 

但是可能会发生这样一个问题,当我们不断的增加小呆呆的数量,小呆呆达到一定的数量之后,这样不但没有提高效率,反而会给CPU增加负担.因此在真实的程序中,确定线程的数量,需要反复的测试.

 还有可能出现以下问题

当还有一个棒棒糖的时候.,但这是有两个小呆呆,这个时候两个小呆呆争抢一个棒棒糖,会出现线程不安全的问题.

二.线程的创建

Java中的JDK给我们提供了API来创建线程(Thread类)

1.继承Thread类

public class Demo2_Thread {
    public static void main(String[] args) {
        MyThread02 thread02 = new MyThread02();
        thread02.start();
        while (true){
            System.out.println("main thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}
class MyThread02 extends Thread{
    @Override
    public void run() {
        while (true){
            System.out.println("my thread ");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

run()方法中表示的就是这个线程中需要执行的任务

注意: 我们自定义的继承的Thread的类重写的是run()方法,而我们启动的线程的时候调用的是start()方法,如果我们调用成了run()方法,就仅仅是类中一个方法的调用,而start()方法才是创建一个线程,具体我们可以看一下源码start()方法.

 代码的运行结果

 从代码的运行结果我们可以总结出两个线程(主线程main和my thread)并不是有序执行的,因为CPU的调度是随机的.   线程的执行是抢占式执行

2.实现Runnable接口重写run()方法

public class Demo3_Runnable {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        //创建线程
        Thread thread = new Thread(myRunnable);
        thread.start();
        while (true) {
            System.out.println("main thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

class MyRunnable implements Runnable {
    //需要执行的任务
    @Override
    public void run() {
        while (true) {
            System.out.println("生产皮包,金币+1");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {

            }
        }

    }
}

使用Runnable定义任务的好处:

1.解耦,把定义线程和定义任务分开 

2.将定义线程和定义任务分开 ,以便修改代码时可以统一的进行修改

解耦:把不同的功能分开,如何要修改或查找指定的功能的代码可以到指定位置进行操作.

3.通过匿名内部类的方式创建Thread和实现Runnable

public class Demo4_Annoation {
    public static void main(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("hello Thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        thread.start();
        while (true){
            System.out.println("main thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

4.通过Lambda表达式来实现一个线程

对Lambda表达式不熟悉的可以看这一篇博客:Java8新特性之Lambda表达式和Stream API

public class Demo5_Lambda {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            while (true) {
                System.out.println("hello Thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread.start();
        while (true){
            System.out.println("main thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

 其实这个就是类似于实现Runnable,因为Runnable接口是一个函数式的接口,而且其中的方法run()没有参数,所以可以直接用上面的格式进行实现, 大括号里面就是线程需要执行的功能

三.查看Java中创建线程的状态

1.直接到JDK中寻找jconsole.exe文件

双击打开,找到自己运行的线程进行查看

点击不安全连接进行查看

 点击上方的线程,查看自己的线程信息,默认的线程Thread0开始,也可以在代码中给自己的线程进行命名操作

A3MUCFZVIdtQAAAAAElFTkSuQmCCwAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 2.命令行中直接搜索jconsole

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

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

相关文章

金豺(GJO)优化算法、matlab代码实现以及与PSO、GWO、SO算法比对

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1 算法原理2 算法步骤2.1 初始化种群2.2 搜索猎物(全局搜索)2.3 包围和围捕猎物(局部搜索)2.4 从全局搜索转向局部搜索 3 算法流程图4 m…

(22)目标检测算法之 yolov8模型导出总结

yolov8模型导出总结 不断更新中… 几种部署情况: onnxxmlengine官网说明:https://github.com/ultralytics/ultralytics/blob/main/docs/modes/export.md导出参数: onnx 参数解析format: 导出的模型形式:onnx xml engine ... imgsz: 设置模型的输入尺寸大小,默认640*640 ke…

记录一次docker镜像迁移过程

1.在母本服务器上查看要复刻的docker镜像。 sv800:build 作为docker镜像源[repository:tag],使用docker save 指令提出docker镜像包rk3588.tar docker save -o rk3588.tar sv800:build 2.在新环境下加载docker镜像包,预先安装docker指令工具 docker load -i rk35…

OCT图像中的多尺度无监督视网膜水肿区域分割

文章目录 Multiscale Unsupervised Retinal Edema Area Segmentation in OCT Images摘要本文方法原始的DCCS无监督图像聚类Pseudo-Mask-Guided Pixel-Wise Segmentation 实验结果 Multiscale Unsupervised Retinal Edema Area Segmentation in OCT Images 摘要 提出了一种新的…

STM32F051K8U6按键中断实例

引言 最近要开始做毕设了,准备用STM32做一个平衡小车,好久没做过STM32的裸机项目了,做几个项目练练手,复习一下。本例程使用STM32CubeMX配套hal库来实现按键中断和串口中断。芯片用的是STM32F051K8U6。 一、按键中断 &#xff0…

iproute2和流量控制(ip和tc工具)---iproute2/ip/tc/qdisc实现Linux下的QoS控制

iproute2是一个软件包,这个软件包包含了多种用于高级路由,隧道和流量控制配置工具软件。 iproute2提供了Linux内核对QoS的实现,你可以在以下网站中找到英文原版的信息osdl.org和lartc.org。这些工具软件中,最重要的当数ip和tc这二…

【Flutter从入门到入坑之五】你真的会使用 Widget 中的 State 吗?

【Flutter从入门到入坑】Flutter 知识体系 【Flutter从入门到入坑之一】Flutter 介绍及安装使用 【Flutter从入门到入坑之二】Dart语言基础概述 【Flutter从入门到入坑之三】Flutter 是如何工作的 【Flutter从入门到入坑之四】构建Flutter界面的基石——Widget State 前沿UI 编…

2023 年 3 月青少年机器人技术等级考试理论综合试卷(一级)

2023 年 3 月青少年机器人技术等级考试理论综合试卷(一级) 一、单选题(共 30 题,共 60 分) 1.关于使用动滑轮说法正确的是?( B) A. 是否省力与动滑轮的颜色有关 B.可以改变力的大小 C.不能省力 D.动滑轮的位…

AUTOSAR知识点Com(十三):ComM内容分析

目录 1、概述 1.1、总览 1.2、功能描述 1.3、依赖关系 2、功能SPEC 2.1、PNC 2.2、通道状态机 2.3、时序图解析 3、COMM工具配置 3.1、ComMGeneral 3.2、ComMConfigSet 1、概述 1.1、总览 ComM的全程是Communication Manager 管理通信,是BSW里面的一个组…

关于大模型对未来影响的一点看法

人们总是高估了未来一到两年的变化,低估了未来十年的变革。 ---比尔盖茨 近来OpenAI的GPT技术可以说在全球都带来了巨大的影响,也让大家看到了什么叫大力出奇迹。chatGPT和GPT4的能力给了大家很大的震撼,其流畅自如、逻辑清晰、出众的能力&am…

【vscode远程开发】使用SSH远程连接服务器 「内网穿透」

文章目录 前言视频教程1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 转…

Rosetta从头蛋白抗体设计、结构优化及在药物研发中的应用

Rosetta从头蛋白抗体设计、结构优化及在药物研发中的应用 第一天 内容 主要知识点 从蛋白质折叠到蛋白质设计教学目标:了解本方向内容、理论基础、研究意义。 蛋白质折叠与结构预测简介 主链二面角与二级结构侧链堆积与三级结构蛋白质设计简介 蛋白质设计的分…

shell编程之条件语句__例题

文章目录 (1) 检查用户家目录中的test.sh文件是否存在,并且检查是否有执行权限. [rootclr /opt/mywork]# cat 1.sh #!/bin/bash #检查用户家目录中的 test.sh 文件是否存在,并且检查是否有执行权 cd /roottest -f test.shif [ $? -eq 0 ];thentest -x…

插件、组件、控件,你分得清吗?

最近和小伙伴交流,时常发生插件、组件、控件等概念混淆的情况,因此导致经常会错意。感觉还是很有必要带大家整理清楚的,今天就来跟大家来聊一聊插件、组件、控件的区别。 什么是插件 先按照官方的一些解释来看看插件的概念描述?…

搭建Debug(printf)Viewer调试环境

希望对KEIL开发的小白的有用&#xff0c;KEIL开发如果高效正确调用Printf 打印输出调试信息。 需要添加红色字体代码 #include <stdio.h> #define ITM_Port8(n) (*((volatile unsigned char *)(0xE00000004*n))) #define ITM_Port16(n) (*((volatile unsigned short *)(…

Android类似微信聊天页面教程(Kotlin)五——选择发送图片

前提条件 安装并配置好Android Studio Android Studio Electric Eel | 2022.1.1 Patch 2 Build #AI-221.6008.13.2211.9619390, built on February 17, 2023 Runtime version: 11.0.150-b2043.56-9505619 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 11 …

【模拟IC学习笔记】 负反馈系统的稳定性

反馈方程 输出方程 误差方程 环路增益 定义:当输入电压接地、并将环路断开时&#xff0c;所计算的增益就是环路增益 时&#xff08;幅度1&#xff0c;相位-180&#xff09;电路稳定在电源或低状态或在电源和地之间振荡。 分析稳定性时是对环路增益进行分析&#xff0c;通过环…

Java+Selenium+Testng自动化学习(一):环境搭建

目录 一、软件准备及版本介绍&#xff1a; 二、安装步骤及环境变量配置&#xff1a; 2.1 Java安装及配置 2.2 IDE工具&#xff08;Intellij IDEA&#xff09;安装及配置 2.3 Maven安装及配置 2.4 Maven本地仓库配置 2.5 Intellij IDEA配置mvn 一、软件…

全开放式时代来临,南卡OE带给你非同寻常的舒适和听觉感受

NANK南卡一直致力于深耕音频领域&#xff0c;不断创新&#xff0c;将于五月份发布全新形态的全开放式蓝牙耳机。相较于传统耳机&#xff0c;开放式蓝牙耳机除了佩戴零感舒适&#xff0c;还能在沉浸音乐的同时与外界保持沟通。南卡OE作为新推出的开放式蓝牙耳机&#xff0c;采用…

7年从测试废物到测试主管,如何从纯功能测试内卷中破局?

我大学学的计算机专业&#xff0c;有一点编程基础。我的软件测试职业开始和大多数测试人员一样&#xff0c;一开始在一家电商公司做软件功能测试。 大部分进入测试行业的朋友&#xff0c;最开始接触都是纯功能界面测试&#xff0c;随着工作年限&#xff0c;会接触到一些常用测试…