java中多线程、并发、并行、线程与进程、线程调度、创建线程的方式

news2024/9/29 3:32:17

多线程

多线程比单线程快,前面简单介绍过:集合如果是不安全的,那么它就是多线程的,了解多线程之前,先了解什么是并发和并行。

并发:指两个或多个事件在同一个时间段内发生。

并行:指两个或多个事件在同一时刻发生,这里强调同一时刻,并行的速度快于并发。
请添加图片描述
线程与进程:

进程:指一个内存中运行的应用程序,每个进程都有一个独立的空间,一个应用程序可以同时运行多个进程,进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个程序从创建到运行再到消亡的过程。
请添加图片描述
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程,一个进程中是可以有多个线程的,这个应用程序可以称为多线程程序。简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。

CPU:计算机中央处理器,可以对数据进行计算,指挥计算机中软件和硬件工作。
请添加图片描述
线程调度

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

抢占调度:优选让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个线程执行,java使用的是抢占式调度。
请添加图片描述
创建线程类:

主线程:执行主方法(main)的线程被称作主线程。

单线程实现一个业务:

// 主线程:执行主方法(mian)的线程
// java默认是单线程的,从mian方法中开始,从上到下依次执行。
public class MainClass {
    public static void main(String[] args) {
        // 创建第一个对象:
        Person p1 = new Person("小明");
        p1.consoleHandle();

        // 创建第二个对象:
        Person p2 = new Person("小红");
        p2.consoleHandle();

        // 执行此程序,可以看到到上面部分从上到下依次执行:
        // 小明--0
        // 小明--1
        // 小红--0
        // 小红--1
        
        System.out.println(1 / 0); // 执行完上面的代码后,从这里开始报错Exception in thread "main"单线程程序中,抛出异常后,后面的代码将不能在执行,多线程的话可以将多个业务放到不同的线程中去,这样即使一个线程中抛出了异常,另一个线程也不会被影响到。
        System.out.println(5);
    }
}

创建一个多线程程序

在lang包下有一个Thread类,代表线程,用来描述多个线程。java中创建线程有两种方式。

方式一:将类声明为Thread的子类,该子类应该重写Thread的run方法,,如:

定义一个多线程的类:

// 创建线程的第一种方式:创建Thread子类:
// 想要实现多线程,就要继承Thread类,其步骤:1.创建一个Thread子类、2.在该子类中重写run方法,设置线程任务(该线程要做什么)3.创建该类的实例对象 4.调用该实例的start方法开启新的线程(调用start方法会开辟新的线程,虚拟调用该线程的run方法)
// run执行的结果是两个线程并发的运行,当前线程(main线程,从调用返回给start方法)和另一个线程(创建的新线程,执行其run方法)
// start方法,一个线程只能调用一次,多次启动一个线程是非法的,特别是当线程已经结束执行后,不能再重新启动。

// 1.创建一个Thread的子类:
public class OneThreadClass extends Thread {
    // 2.重写run方法
    @Override
    public void run () {
        // run方法里面用来设置任务,这里还是以循环为例:
        for (int i = 0; i < 2; i++) {
            System.out.println("run1--" + i);
        }
    };
}

实例化一个多线的类:

public class TestOneThreadClass {
    public static void main(String[] args) {
        // 3.创建一个多线程类的实例:
        OneThreadClass ot = new OneThreadClass();
        // 4.调用该实例的start方法(start方法继承于Thread类)让其调用run方法来执行任务:
        ot.start();

        // 主线程也执行for
        for (int i = 0; i < 2; i++) {
            System.out.println("main--" + i);
        }

        // 打印到控制台的结果如下:可以看到此时程序不是从上到下依次执行了,原因是这里是个多线程的,多个线程抢占cpu执行,同一优先级随机选择一个线程执行
        // main--0
        // run1--0
        // main--1
        // run1--1
    }
}

程序执行图:
请添加图片描述
内存图:
请添加图片描述
Thread类的常用方法

创建一个继承Thread的类:

public class MyThread extends Thread {
    public MyThread() {
    }

    // 4.修改线程名称还有一种方式就是通过构造方法调用super将名称传给super,注意重载格式是(String name)这个,如:
    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run () {
        // 1.Thread类的getName可以获取到线程的名称:
        String nm = getName();
        System.out.println(nm); // Thread-0, 每创建一个线程,并执行start方法后,会新增一个后面索引增加1的新线程

        // 2.Thread类的currentThread返回当前正在执行的线程对象的索引:
        System.out.println(Thread.currentThread()); // Thread[Thread-1,5,main] 和 Thread[Thread-0,5,main] Thread[线程001,5,main] Thread[线程003,5,main]
        System.out.println(Thread.currentThread().getName()); // Thread-0 和 Thread-1 线程001 线程003
    };
}

使用继承了Thread类的类:

public class UseMyThread {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        mt.start();

        new MyThread().start();

        // 3.Thread类的setName(String name)设置线程的名字:
        MyThread mt2 = new MyThread();
        mt2.setName("线程001");
        mt2.start();

        // 4-2:对构造方法直接修改名称的测试:
        MyThread mt3= new MyThread("线程003");
        mt3.start();

        // 5.Thread的sleep(mills)方法,让线程休眠n毫秒后继续执行,如:正常一个循环会很快的执行完,此时用sleep给它休眠5000毫秒执行,就可以看到每各5秒钟打印一次:
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
            try {
                // 本身会报异常,使用try/catch处理下即可
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

创建多线程的第二种方式(推荐方式):

继承Runnable接口实现类:

// 1.创建一个Runnable接口的实现类
public class RunnableTmplClass implements Runnable {
    // 2.在实现类中重写Runnbale接口的run方法,设置线程任务
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "--" + i);
        }
    }
}

测试第二种方式实现多线程:

// 创建多线程的第二种方式:实现Runnable接口:
// Runnable接口应该由那些打算通过某一线程执行某实例的类来实现,类必须定义一个称为run的无参数方法。
// 实现步骤: 1.创建一个Runnable接口的实现类 2.在实现类中重写Runnbale接口的run方法,设置线程任务 3.创建一个Runnable接口的实现类对象 4.创建Thread类对象,构造方法中传递Runnable接口实现类对象 5.调用Thread类中的start方法,开启新的线程执行run方法
public class TwoThreadClass {
    public static void main(String[] args) {
        // 3.创建一个Runnable接口的实现类对象
        RunnableTmplClass rt = new RunnableTmplClass();
        // 4.创建Thread类对象,构造方法中传递Runnable接口实现类对象
        Thread td = new Thread(rt);
        // 5.调用Thread类中的start方法,开启新的线程执行run方法
        td.start();
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "--" + i);
        }
    }
}

前两种创建线程方式之间的区别:

1.实现Runnable接口创建多线程:

避免了单继承的局限性(一个类只能继承一个父类,如果类继承了Thread类后就无法再继承其他类了),但是实现了Runnable接口后还可以继承其他类,实现其他的接口。

2.增强了程序的扩展性,降低了程序的耦合性(解耦,实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离,可以实现多个Runnable接口实现类并设置run方法任务,给Thread类创建对象使用)。

匿名内部类方法实现线程的创建

// 匿名内部类方式实现线程的创建
// 匿名内部类的作用:简化代码,把子类继承父类,重写父类的方法,创建子类对象合在一起完成,把实现类实现接口,重写接口中的方法,创建实现类对象合成一步完成
// 匿名内部类的最终产物:子类、实现类对象,这个类没有名字
// 格式:new 父类/接口(){重复父类/接口中的方法}
public class ThreeThreadClass {
    public static void main(String[] args) {
       // 线程的父类是Thread
        new Thread(){
            @Override
            public void run(){
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + "----" + i);
                }
            };
        }.start();
    }
}

提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:810665436@qq.com联系笔者删除。
笔者:苦海

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

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

相关文章

高通平台开发系列讲解(AtCoP篇)AtCoP架构简介

文章目录 一、ATCoP简介二、ATCoP架构三、流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇讲介绍高通ATCoP的架构。 一、ATCoP简介 ATCoP(AT Command Processor)是高通平台对于AT命令处理的模块,通过它,我们可以实现对AT命令的修改和新增。ATCoP接收从串口…

[附源码]Python计算机毕业设计公司办公自动化系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

跟大佬展开激励讨论String的不可变性

目录 大佬证明&#xff1a; 我的证明&#xff1a; 后续 什么是不可变&#xff1f; String为什么不可变 为什么要设计成为不可变的呢&#xff1f; 1.首先我们最先可以想到的Java主要做的就是安全 2.其次是字符串常量池的需要 String真的不可变吗&#xff1f; ps&#…

平淡无奇,2022年终总结

1前言 一年又一年&#xff0c;时间过得太快啦&#xff01; 最近总是想着2022年的点点滴滴&#xff0c;一年时光不得写点什么不一样的&#xff0c;可是思前想后觉得这一年也没什么不一样的啊。所以呢&#xff0c;2022年终总结标题就取名为平淡无奇。 人一生最重要的是什么&#…

Java Servlet + H2数据库之集成环境配置

在 EclipseMavenTomcat 集成开发环境配置 搭建了一个Servlet的开发环境&#xff0c;整合Tomcat 作为Web容器。如何要加入数据库开发要怎么处理呢&#xff1f; 在实际开发中&#xff0c;一般会选择MySQL&#xff0c;Oracle 等数据库&#xff0c; 但是如果只是学习和演示&#x…

DPDK源码分析之网络基础知识

字节对齐 attribute ((aligned (1))); 在设计不同CPU下的通信协议时&#xff0c;或者编写硬件驱动程序时寄存器的结构这两个地方都需要按一字节对齐。即使看起来本来就自然对齐的也要使其对齐&#xff0c;以免不同的编译器生成的代码不一样. 如果跨越了4字节边界存储&#xff…

java之JVM的位置和体系结构

JVM的概念&#xff1a; JVM 即 Java Virtual Machine&#xff0c;中文名为 Java虚拟机&#xff0c;一般情况下&#xff0c;对于C/C 程序&#xff0c;编译成二进制文件后&#xff0c;就可以直接执行了&#xff0c;但Java 需要使用 javac 编译成 .class 文件&#xff0c;还需要使…

【LSTM回归预测】基于matlab主成分分析结合BiLSTM数据回归预测【含Matlab源码 2276期】

一、LSTM和BiLSTM神经网络结构及原理介绍 长短期记忆网络(Long short-term memory, LSTM)实质上可以理解为一种特殊的RNN,主要是为了解决RNN网络在长序列训练过程中发生梯度消失和梯度爆炸的问题。相比于RNN,LSTM主要是引入了细胞形态(cell state)用于保存长期状态&#xff0c…

世界杯决赛倒计时,你最看好谁

一、期待终极决赛 C站肯定有许多看球的朋友吧。明天即将迎来2022年世界杯终极对决&#xff0c;阿根廷队对战法国。来赶个晚集&#xff0c;也来聊聊世界杯&#xff0c;下一个四年就是2026&#xff0c;会不会还有这种精神呢。先来回顾一下本轮世界杯比赛中的对阵吧。 本轮世界杯中…

Win11+RTX3060+Anconda+CUDA11.3+cuDNN8.2+Pytorch1.10一条龙服务2

Win11RTX3060AncondaCUDA11.3cuDNN8.2Pytorch1.10一条龙服务 &#xff08;1&#xff09;查看安装了哪些包 conda list&#xff08;2)查看当前存在哪些虚拟环境 conda env list &#xff08;3&#xff09;创建虚拟环境&#xff0c;你可以创建好几个虚拟环境&#xff0c;虚拟环…

Flex布局小练--博文列表item布局实现

文章目录前言元素组成实现html部分布局总结前言 今天划一个水先&#xff0c;没办法&#xff0c;作孽没写完&#xff0c;什么这不是作孽的一部分嘛&#xff1f;&#xff01;听不见&#xff0c;听不见。 来先看一下我们要做的一个效果&#xff1a; 首先是这个页面下面的&#xf…

如何基于Jetbrains IDEA DataBase从数据库表中生成对应的Java Bean

在日常的项目开发过程中&#xff0c;大部分人可能都会遇到过想从表自动生成带有注释的Java Bean&#xff0c;在Jetbrains IDEA中通过DataBase工具也是可以生成的。Jetbrains IDEA的Database借助一个名称为Generate POJOs.groovy的groovy模板文件&#xff0c;可以帮我们做代码生…

Python工程师Java之路(t)SpringBoot部署步骤 java -jar

文章目录步骤1、开发环境2、新建工程3、新建controller4、开发环境试运行和测试5、打包运行命令补充步骤 1、开发环境 WIN10IDEA2021Maven3.6.3JDK1.8 2、新建工程 选择Spring和Java版本 添加依赖 3、新建controller package com.example.demo.controller;import org.spr…

macOS Ventura 13.1 (22C65) Boot ISO 原版可引导镜像

本站下载的 macOS Ventura 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。 2022 年 12 月 13 日&#xff0c;macOS Ventura 13.1 推出了“无边记”&#x…

基于python的PatchMatchStereo立体匹配算法实现

文章目录前言一、PatchMatchStereo是什么&#xff1f;1.随机初始化2.迭代传播2.1空间传播2.2视图传播2.3帧间传播2.4平面细化二、PatchMatchStereo立体匹配算法实现前言 PatchMatchStereo是Michael Bleyer等在2011年发表于British Machine Vision Conference&#xff08;BMVC&a…

机器学习 鸢尾花数据集划分 训练集和测试集

目录 一&#xff1a;加载数据 二&#xff1a;数据集整理 三&#xff1a;数据集划分 一&#xff1a;加载数据 加载数据&#xff0c;并创建一个DataFrame&#xff0c;便于数据分析 from sklearn.datasets import load_iris import pandas as pd import numpy as np from skle…

大数据:计算学生成绩

文章目录一、提出任务二、任务进行&#xff08;一&#xff09;准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录&#xff08;二&#xff09;实现步骤1、创建Maven项目2、添加相关依赖3、创建日志属性文件4、创建成绩映射器类5、创建成绩驱动器类6、启动成绩驱动器类…

【JavaSE】类和对象(三)——内部类

目录 1. 何为内部类 2. 内部类的分类 2.1 静态内部类 2.1.1 如何实例化静态内部类的对象&#xff1f; 2.1.2 外部类与静态内部类如何相互访问&#xff1f; 2.2 非静态内部类/实例内部类 2.2.1 非静态内部类不能定义静态的成员变量以及方法 2.2.2 非静态内部类的实例化 2.2.…

三层-生成树-ospf-速端口思科练习实验

♥️作者&#xff1a;小刘在这里 ♥️每天分享云计算网络运维课堂笔记&#xff0c;疫情之下&#xff0c;你我素未谋面&#xff0c;但你一定要平平安安&#xff0c;一 起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放&#xff0c;…

Spark-SaprkStreaming(概述、架构、原理、DStream转换、案例)

文章目录SparkStreaming概述特点架构原理DStream和RDD的区别DAG如何读取数据(※)WordCount 案例实操代码解析RDD 队列用法及说明案例实操自定义数据源Kafka 数据源DStream 转换无状态转化操作Transformjoin有状态转化操作UpdateStateByKeyWindowOperationsDStream 输出优雅关闭…