【Java进阶】多线程&高并发(一)<线程概述>

2023-10-26

一、线程相关概念

1. 进程

  • 进程(process)是计算机中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配与调度的基本单位
  • 进程可以简单理解为正在操作系统中运行的一个程序

2. 线程

  • 线程(thread)是进程的一个执行单元
  • 一个线程就是进程中一个单一顺序的控制流,是进程的一个执行分支

3. 进程和线程区别

  • 进程是线程的容器,一个进程至少有一个线程,一个进程中可以有多个线程
  • 在操作系统中是以进程为单位分配资源的,如:虚拟存储空间、文件描述符等
  • 每个线程都有各自的线程栈,自己的寄存器环境,自己的线程本地存储

4. 主线程和子线程

  • JVM启动时会创建一个主线程,该主线程负责执行main()方法,主线程就是运行main()方法的线程
  • Java中的线程不是孤立的,线程之间存在一些联系,如果在A线程中创建了B线程,称B线程是A线程的子线程,相应的A线程就是B线程的父线程

5. 串行、并发和并行

在这里插入图片描述

  • 并发可以提高事物的处理效率,即一段时间内可以处理或者完成更多的事情
  • 并行是一种更为严格、理想的并发
  • 从硬件角度来说,如果单核CPU,一个处理器一次只能执行一个线程的情况下,处理器可以使用时间片轮转技术,可以让CPU快速的在各个线程之间进行切换,对于用户来说,感觉是三个线程在同时执行。如果是多核心CPU,可以为不同的线程分配不同的CPU内核

二、线程的创建与启动

1. 介绍

  • 在Java中,创建一个线程就是创建一个Thread类(子类)的对象(实例)
  • Thread类有两个常用的构造方法:Thread()和Thread(Runnable),对应的创建线程的两种方式,这两种创建线程的方式没有本质的区别
    ① 定义Thread类的子类
    ② 定义一个Runnable接口的实现类

2. 继承Thread类

  • 基本使用
package Thread;

/**
 * 继承Thread类
 *
 * @author swaggyhang
 * @create 2023-06-14 19:51
 */
public class ExtendsThreadDemo {
    public static void main(String[] args) {
        System.out.println("JVM启动main线程,main线程执行main()方法");
        // 3 创建子线程对象
        MyThread thread = new MyThread();

        // 4 启动线程
        thread.start();

        /**
         * 1)调用线程的start()方法来启动线程
         * 2)启动线程的实质就是请求JVM运行相应的程序,这个线程具体在什么时候运行,由线程调度器(Scheduler)决定
         * 3)start()方法调用结束并不意味着子线程运行开始
         * 4)新开启的线程会执行run()方法
         * 5)如果开启了多个线程,start()方法调用的顺序并不一定就是线程启动的顺序
         * 6)多线程运行结果与代码执行顺序或调用顺序无关
         */
        System.out.println("main线程后面其他的代码...");
    }
}

// 1 定义类继承Thread
class MyThread extends Thread {

    // 2 重写Thread类的run()方法
    // run()方法体中的代码就是子线程要执行的任务
    @Override
    public void run() {
        System.out.println("这是子线程打印的内容");
    }
}
  • 多线程运行结果是随机的
package Thread;

/**
 * 多线程运行结果是随机的
 *
 * @author swaggyhang
 * @create 2023-06-14 20:21
 */
public class ThreadRandomDemo {
    public static void main(String[] args) {
        MyThread2 thread2 = new MyThread2();
        thread2.start();    // 开启子线程

        // 当前是main线程
        try {
            for (int i = 0; i < 10; i++) {
                System.out.println("main--:" + i);
                int time = (int) (Math.random() * 1000);
                Thread.sleep(time); // 线程睡眠,单位是毫秒
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class MyThread2 extends Thread {
    @Override
    public void run() {
        try {
            for (int i = 0; i < 10; i++) {
                System.out.println("sub thread:" + i);
                int time = (int) (Math.random() * 1000);
                Thread.sleep(time); // 线程睡眠,单位是毫秒
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3. 实现Runnable接口

package Thread;

/**
 * 当线程类以及有父类了,就不能用继承Thread类来创建线程,可以使用实现Runnable接口来创建线程
 *
 * @author swaggyhang
 * @create 2023-06-14 20:56
 */
public class ImplementsRunnableDemo {
    public static void main(String[] args) {
        // 3 创建Runnable接口的实现类对象
        MyRunnable runnable = new MyRunnable();
        // 4 创建线程对象
        Thread thread = new Thread(runnable);
        // 5 开启线程
        thread.start();

        // 当前是main线程
        for (int i = 0; i < 10000; i++) {
            System.out.println("main ==> " + i);
        }

        // 有时调用Thread(Runnable)构造方法时,实参也会传递匿名内部类对象
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    System.out.println("sub ----------------> " + i);
                }
            }
        });
        thread2.start();
    }
}

// 1 定义类实现Runnable接口
class MyRunnable implements Runnable {
    // 2 重写Runnable接口中的抽象方法run(),run()方法就是子线程要执行的代码
    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println("sub thread --> " + i);
        }
    }
}

三、线程的常用方法

1. currentThread()方法

  • Thread.currentThread()方法可以获得当前线程
  • Java中的任何一段代码都是执行在某个线程当中的,执行当前代码的线程就是当前线程
  • 同一段代码可能被不同的线程执行,因此当前线程是相对的
  • Thread.currentThread()方法的返回值是在代码实际运行时候的线程对象
  • 基础使用
package Thread;

/**
 * @author swaggyhang
 * @create 2023-06-14 21:15
 */
public class CurrentThreadDemo {
    public static void main(String[] args) {
        System.out.println("main方法中打印当前线程:" + Thread.currentThread().getName());

        // 创建子线程,调用SubThread1()构造方法,在main线程中调用的,因此构造方法中的当前线程就是main线程
        SubThread1 t1 = new SubThread1();
        t1.start(); // 启动子线程,子线程会调用run()方法,因此run()方法中的当前线程就是Thread-0子线程

        t1.run();   // 在main()方法中直接调用run()方法,没有开启新的线程,因此在run()方法中的当前线程是main线程
    }
}

class SubThread1 extends Thread {
    public SubThread1() {
        System.out.println("构造方法打印当前线程名称:" + Thread.currentThread().getName());
    }

    @Override
    public void run() {
        System.out.println("run方法打印当前线程名称:" + Thread.currentThread().getName());
    }
}
  • 复杂案例
package Thread;

/**
 * @author swaggyhang
 * @create 2023-06-14 21:24
 */
public class CurrentThreadComplexDemo {
    public static void main(String[] args) throws InterruptedException {
        // 创建子线程对象
        SubThread2 t2 = new SubThread2();
        t2.setName("t2");   // 设置线程名称
        t2.start();

        Thread.sleep(500);  // main线程睡眠500毫秒,保证t2线程已经启动

        // Thread(Runnable)构造方法形参是Runnable接口,调用时传递的实参是该接口的实现类对象
        Thread t3 = new Thread(t2);
        t3.start();
    }
}

class SubThread2 extends Thread {
    public SubThread2() {
        System.out.println("构造方法中,Thread.currentThread().getName():" + Thread.currentThread().getName());
        System.out.println("构造方法中,this.getName():" + this.getName());
    }

    @Override
    public void run() {
        System.out.println("run方法中,Thread.currentThread().getName():" + Thread.currentThread().getName());
        System.out.println("run方法中,this.getName():" + this.getName());
    }
}

2. setName()/getName()方法

  • thread.setName(线程名称),设置线程名称
  • thread.getName()返回线程名称
  • 通过设置线程名称,有助于程序调试,提高程序的可读性,建议为每个线程都设置一个能够体现线程功能的名称

3. isAlive()方法

  • thread.isAlive()判断当前线程是否处于活动状态
  • 活动状态就是线程已经启动并且尚未终止
package Thread;

/**
 * 线程的活动状态
 *
 * @author swaggyhang
 * @create 2023-06-14 21:51
 */
public class IsAliveDemo {
    public static void main(String[] args) {
        SubThread3 t3 = new SubThread3();
        System.out.println("begin==,isAlive = " + t3.isAlive());    // false,在启动线程之前
        t3.start();
        System.out.println("end==,isAlive = " + t3.isAlive());  // 结果不一定,打印这一行时,如果t3线程还没结束就返回true,结束了就返回false
    }
}

class SubThread3 extends Thread {
    @Override
    public void run() {
        System.out.println("run方法,isAlive = " + this.isAlive());
    }
}

四、线程的生命周期

五、多线程编程的优势与存在的风险

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Java进阶】多线程&高并发(一)<线程概述> 的相关文章

  • Eclipse Californium CoAP 通配符作为 url 路径

    我正在使用 Eclipse Californium 开发一个 CoAP 应用程序 它将仅显式声明根资源路径 其余资源应通过通配符提供和解析 root 就像在 REST API 或 servlet 上一样 有什么办法可以实现这一点吗 好吧 我
  • Jackson JSON、不可变类和接口

    我正在使用 Jackson 的示例 并且在反序列化与不可变的类和接口一起使用时遇到了一些麻烦 下面是我的代码 package com art starter jackson starter import java io IOExceptio
  • Android - 从HashMap中获取值

    我尝试在 Android 中搜索 HashMap 但出现问题 考虑这个例子 HashMap
  • JTable 未显示在 JFrame (Java) 上

    我遇到了一个问题JFrame没有显示JTable添加到其中 我试过了getContentPane add 我已改为仅添加以使代码更短一些 任何帮助都非常感激 package com embah Accgui import java awt
  • 已完成 Java 项目,现在创建 jar 或 .exe 文件(带有数据库)

    所以 我刚刚完成了一个小的java应用程序 带有数据库和其他东西 我使用了 Netbeans 和 Mysql 现在我想导出我的项目 这样我就可以在任何我想要的地方使用它 任何计算机 即使没有安装 Mysql 或 Java 所以 我尝试了一些
  • 无法应用插件 [id 'forge']

    这是一个延续这个问题 https stackoverflow com questions 58312064 upgrading gradle我的第一个问题已经解决了 但是新的问题又出现了 按照其中提到的教程 解决了一些错误后 现在当我尝试运
  • Apache CXF 客户端代理设置

    我正在尝试使用以下教程开发肥皂服务的消费者http cxf apache org docs developing a consumer html http cxf apache org docs developing a consumer
  • 如何像在 Matlab 中一样在 Java 中绘制绘图(相同语法)

    在 Matlab 中绘图非常简单明了 例如 figure Position 100 80 1000 600 plot x y1 or MarkerSize 0 2 MarkerFaceColor r LineWidth 2 xlabel M
  • 在 Java 中通过 JDBC 查询速度慢,但在其他系统(TOAD)中则不然

    您好 我有一个对 Oracle 系统的查询 其中涉及一个视图 该视图通过将 TO NUMBER 应用于表主键来连接其他表 如果我使用 TOAD 进行查询 查询速度非常快 800 个寄存器 1 秒 如果我通过 JDBC 使用字符串文字 不是参
  • 使用 post 方法打开 URL android

    我必须向网址发送一些参数并打开它 但我不知道该怎么做 var variables URLVariables new URLVariables variables param1 param1 variables param2 param2 v
  • java并发:多生产者一消费者

    我遇到一种情况 不同的线程填充一个队列 生产者 并且一个消费者从该队列中检索元素 我的问题是 当从队列中检索这些元素之一时 某些元素会丢失 丢失信号 生产者代码是 class Producer implements Runnable pri
  • Java:CopyOnWriteArrayList 与 SynchronizedList

    有什么区别CopyOnWritearraylist and Collections synchronizedList 什么时候应该优先选择其中一个 CopyOnWriteArrayList当读取次数远远超过写入次数时 应使用列表 这是因为您
  • 对字符串数组使用快速排序

    我是一名编程学生 我不会发布整个作业 而是请求帮助解决我已经尝试了几个小时才能理解的问题 我的任务是使用快速排序方法对字符串数组进行排序 作为这个问题的一部分 我承担的其他所有任务都很好 但是当我通过打印字符串数组来测试排序方法时 它完全混
  • 如何在 Intellij IDEA 中使用本机库制作 jar?

    如何在 Intellij IDEA 中使用本机库制作 jar 在 JVM 中 它看起来像 Djava library path C Users User workspace lib native win None
  • JSF 2.0 无法从 primefaces 渲染对话框

    最近我在使用 primefaces 组件时遇到了很多问题 我不知道为什么 我使用glassfishV3 0 我的primefaces版本是2 2 1 我现在的问题是 当我单击表行时 我无法使 primefaces 的 p dialog 呈现
  • 使用PHP openssl_verify()函数验证Android客户端APP创建的签名和数据

    我读到了关于帖子openssl verify http php net manual en function openssl verify php 我想问一些与openssl verify 因为我的 PHP 代码无法验证从 Java 创建的
  • 使用 Java 将 PDF 页面导出为一系列图像

    我需要将任意 PDF 文档的页面导出为 jpeg png etc 格式的一系列单独图像 我需要在 Java 中执行此操作 虽然我确实了解 iText PDFBox 和各种其他 java pdf 库 但我希望能找到一些工作示例或一些操作方法
  • JacksonFeature 破坏了 JsonIgnoreProperties

    我有这样的 pojo JsonIgnoreProperties ignoreUnknown true public class SNAPIResponse public String status public String message
  • Jodatime 是否有方法获取自某个较旧日期以来的月份和日期?

    我想确切地知道某个较早的日期距离今天有多少个月和天 可能是几年 有没有办法做到这一点 我知道如何获得月份的差异 我知道如何获得天数的差异 但我无法获得月份和日期 Ex 旧 2013 03 04 现在 2013 04 17 所以我寻找的结果类
  • JFormattedTextField 未正确清除

    我正在做这个作业 制作一个解决数独的程序 我有一个带有 SudokuTextBox 网格扩展 JFormattedTextField 的面板 我有一个 MaskFormatter 因此每个文本框只接受一个整数 然后在我的面板中 当释放按键时

随机推荐

  • sql查询每个学生的最高成绩mysql语句

    张三 语文 100 张三 数学 83 李四 语文 88 李四 数学 100 查询每个学生的最高成绩 select b from select name max score score from course GROUP BY name a
  • 微信小程序调用域名服务器的服务

    微信小程序得益于它的简单便捷 在日常生活中应用的很普遍 做过开发的同学都知道 微信的前端比较简单易懂 并且微信自带云开发 提供云存储 可以满足一些商家或者自媒体的需求 如果企业类的用户使用小程序 数据是存在企业自己的服务器上 小程序也提供了
  • echarts的展示区域地图,添加纹理图片

    echarts的展示区域地图 添加纹理图片 下面我们以广西南宁的来做实例 来进行这个渲染和添加纹理图片的操作 首先我们先看看文档 echarts 的geo的areaColor是可以支持通过图片来对地图的区域内容来进行纹理填充的 也可以进行颜
  • 操作系统笔记整理10——输入输出系统(2)

    点此链接可跳转到 操作系统笔记整理 目录索引页 参考书籍 计算机操作系统 第四版 汤小丹等编著 文章目录 点此链接可跳转到 操作系统笔记整理 目录索引页 用户层I O软件 系统调用 库函数 假脱机 Spooling 系统 SPOOLing的
  • vue同意本站协议的制作

    div p msg p h5 表单提交 h5 div
  • Echarts遇到Vue3时遇到的问题

    将vue2的Echarts代码迁移到了vue3项目上 引发的问题 问题描述 1 点击图例legend时刻度轴偏移 图像不展示 以及报错 初始chart正常 图 点击图例后的chart和报错 图 2 调用resize 不生效且报错 初始正常
  • mysql之mysql约束19

    概述 本篇是我们DDL语言的最后一篇 从库和表的管理到本篇共3篇 1 mysql约束 常见约束 1 含义 一种限制 用于限制表中的数据 为了保证表中的数据的准确和可靠性 2 分类 六大约束 1 NOT NULL 非空 用于保证该字段的值不能
  • TypeScript -- ts的编译、类型注解、数组类型、联合类型、类型别名、函数类型、对象类型、接口类型、字面量类型、类型推断、类型断言、泛型、any类型

    TypeScript ts的编译 类型注解 数组类型 联合类型 类型别名 函数类型 对象类型 接口类型 字面量类型 类型推断 类型断言 泛型 any类型 TypeScript相较于JavaScript来说 是在js的基础上进行了制约 对原先
  • vmware克隆Centos6.4虚拟机网卡无法启动问题

    问题现象 通过vmware8的完全克隆功能快速创建一台版本为CentOS 6 4的linux虚拟机 创建后症状 启动之后使用ifconfig 发现无ip地址 只有回环地址为127 0 0 1MAC地址以及主机名都和源主机相同 源主机采用手动
  • 算法训练营第三十六天(8.26)

    目录 Leecode 198 打家劫舍 Leecode 213 打家劫舍 II Leecode 337 打家劫舍III Leecode 198 打家劫舍 题目地址 力扣 LeetCode 官网 全球极客挚爱的技术成长平台 题目类型 打家劫舍
  • Android Studio快捷键的设置

    设置好主题和字体之后 http blog csdn net yzzdmzdfq article details 51291322 很多小伙伴们开始迫不及待的编程了 很快就会发现 好像快捷键用起来不太舒服 于是想要设置一下快捷键 那么问题来了
  • JS原型、原型链到底是什么?

    前言 在js的学习中 原型毫无疑问是一个难点 但也是一个不可忽视的重点 在前端面试中也是一个高频考题 在接下来的深入学习中 你会发现原型 原型链等知识点其实并不难 1 一切皆为对象 JavaScript是一个面向 原型 对象的语言 对象是属
  • Linux网络基础 — 网络层

    目录 IP协议 IP协议报头格式 网段划分 特殊的IP地址 IP地址的数量限制 私有IP地址和公网IP地址 路由 补充 网络层 在复杂的环境中确定一个合适的路径 IP协议 ip具有将数据从 主机A 跨网络送到 主机B 的能力 主机 配有IP
  • 如何在CMD下增加IP地址

    1 修改IP地址 注意事项 如果是设置有多IP的情况下 将清除其它IP 只保留此次命令中设置的IP地址 netsh interface ip set address name 本地连接 source static addr 192 168
  • 最大区间交

    先将所有区间按照左端点排序 然后遍历所有区间进行以下操作 第i个区间 a b ans max ans min maxr b a 1 maxr max maxr b
  • 从零开始实现C++ TinyWebServer(九)---- 项目知识点总结

    文章目录 前言 项目介绍 为什么要做这样一个项目 项目背景 项目描述 项目功能 项目流程 项目重难点 项目效果 解决方案 个人收获 线程池 线程的同步机制有哪些 线程池中的工作线程是一直等待的吗 如果同时1000个客户端进行访问请求 线程数
  • com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value 'Öйú±ê׼ʱ¼...

    Spring boot使用MyBatis mysql配置运行时报错com mysql cj exceptions InvalidConnectionAttributeException The server time zone value
  • Odoo的XMLRPC调用

    Odoo的XMLRPC调用 使用场景 需要运行脚本调用odoo的模型方法 对数据库进行修改 企业内部有多个系统服务 系统间互相调用模型方法 基本调用过程 服务端定义好模型和方法 服务端odoo orm方法能被调用 加了 api model装
  • pytorch 详解NLLloss 与crossEntry

    NLLloss 与CrossEntry
  • 【Java进阶】多线程&高并发(一)<线程概述>

    一 线程相关概念 1 进程 进程 process 是计算机中的程序关于某数据集合上的一次运行活动 是操作系统进行资源分配与调度的基本单位 进程可以简单理解为正在操作系统中运行的一个程序 2 线程 线程 thread 是进程的一个执行单元 一