Java基础 Day24

news2025/5/31 14:19:18

一、进程和线程

1、进程

(1)概念

进程 (Process) 是计算机中的程序关于某数据集合上的一次运行活动

是系统进行资源分配的基本单位

简单理解:程序的执行过程(正在运行的应用程序)

(2)特性

独立性:每一个进程都有自己的空间,在没有经过进程本身允许的情况下,一个进程不可以直接访问其它的的进程空间

动态性:进程是动态产生,动态消亡的

并发性:任何进程都可以同其它进程一起并发执行

Tips:

并行:在同一时刻,有多个指令在多个CPU上【同时】执行

并发:在同一时刻,有多个指令在单个CPU上【交替】执行

多进程同时工作:对于一个CPU(单核),它是在多个进程间轮换执行的

2、线程

(1)概念

线程(Thread):进程可以同时执行多个任务,每个任务就是线程

(2)多线程的意义

提高执行效率;同时处理多个任务

随着处理器上的核心数量越来越多,现在大多数计算机都比以往更加擅长并行计算

但是,一个线程,在一个时刻,只能运行在一个处理器核心上

Java程序也是一个进程,如果是一个单线程程序,则无法调动处理器的多个核心

二、Java中开启线程的方式

Tips:Java程序默认是多线程的,一条主线程,一条垃圾回收线程

1、法一:继承Thread类

步骤:

(1)编写一个类继承Thread类

(2)重写run方法

(3)将线程任务写在run方法中

(4)创建线程对象

(5)调用start方法开启线程

注意:直接调用run方法并不能开启线程

2、法二:实现Runnable接口

(扩展性更好)

步骤:

(1)编写一个类实现Runnable接口

(2)重写run方法

(3)将线程任务写在run方法中

(4)创建线程任务资源对象

(5)创建线程对象,将资源传入

(6)使用线程对象调用start方法开启线程

public class ThreadDemo2 {
    public static void main(String[] args) {
//        (4)创建线程任务资源对象
        MyRunnable mr = new MyRunnable();
//        (5)创建线程对象,将资源传入
        Thread t1 = new Thread(mr);
//        (6)使用线程对象调用start方法开启线程
        t1.start();

        for (int i = 0; i < 100; i++) {
            System.out.println("main" + i);
        }
    }
}

//(1)编写一个类实现Runnable接口
class MyRunnable implements Runnable {
//    (2)重写run方法
    @Override
    public void run() {
//        (3)将线程任务写在run方法中
        for (int i = 0; i < 100; i++) {
            System.out.println("MyRunnable" + i);
        }
    }
}

3、法三:实现Callable接口

(线程任务有返回值)

步骤:

(1)编写一个类实现Callable接口

(2)重写call方法

(3)将线程任务写在call方法中

(4)创建线程任务资源对象

(5)创建线程任务对象,封装线程资源

(6)创建线程对象,传入线程任务

(7)使用线程对象调用start方法开启线程

public class ThreadDemo3 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable mc = new MyCallable();
        FutureTask<Integer> task = new FutureTask<>(mc);
        Thread thread = new Thread(task);
        thread.start();
        Integer result = task.get(); // 获取线程任务的返回值
        System.out.println(result);
    }
}

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i <= 100; i++) {
            sum += i;
        }
        return sum;
    }
}

三、线程的相关方法

String getName​()

返回此线程的名称

void setName​(String name)

设置线程的名字(构造方法也可以设置名字)

static Thread currentThread()

获取当前线程的对象

static void sleep(long time)

让线程休眠指定的时间,单位为毫秒

setPriority(int newPriority)

设置线程的优先级,从1到10,默认为5

final int getPriority()

获取线程的优先级

final void setDaemon(boolean on)

设置为守护线程

Tips:线程的调度方式分为抢占式调度(随机)和非抢占式调度(轮流)

Java 采用的方式是抢占式调度

提高线程的优先级可以提高该线程抢到CPU的概率

四、线程安全和同步

1、安全问题出现的条件

是多线程环境

有共享数据

有多条语句操作共享数据

2、同步技术

将多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程可以执行

(1)同步代码块

格式:
synchronized(锁对象) {
    多条语句操作共享数据的代码
}

示例:
public class TicketDemo {
    public static void main(String[] args) {
        // 只new了一个TicketTask对象,三个线程共享一份数据
        TicketTask ticket = new TicketTask();
        Thread t1 = new Thread(ticket);
        Thread t2 = new Thread(ticket);
        Thread t3 = new Thread(ticket);
        t1.start();
        t2.start();
        t3.start();
    }
}

class TicketTask implements Runnable {
    private int tickets = 2000;

    @Override
    public void run() {
        while (true) {
            // 建议使用字节码文件作为锁对象
            synchronized (TicketTask.class) {
                if (tickets <= 0) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + " sold " + tickets);
                tickets--;
            }
        }
    }
}   

Tips:锁对象可以是任意对象,但是需要保证多条线程的锁对象,是同一把锁

同步可以解决多线程的数据安全问题,但是也会降低程序的运行效率

(2)同步方法

在方法的返回值类型前面加入 synchronized 关键字

该方法里的代码就变成同步的

静态方法的锁对象是字节码对象,非静态方法的锁对象是 this

(3)Lock 锁

使用 Lock 锁,可以更清晰地看到哪里加了锁,哪里释放了锁

Lock 是接口,无法直接创建对象

public ReentrantLock()

构造方法:创建一个 ReentrantLock 的实例互斥锁

void lock()

加锁

void unlock();

释放锁

3、死锁

两个或者多个线程互相持有对方所需要的资源

导致这些线程处于等待状态,无法前往执行

产生死锁的情况:同步嵌套

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

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

相关文章

提问:鲜羊奶是解决育儿Bug的补丁吗?

在育儿这个"系统工程"中&#xff0c;过度提醒就像冗余代码&#xff1a;"快写作业"&#xff08;重复调用&#xff09;、"多穿衣服"&#xff08;异常捕获&#xff09;、"别玩手机"&#xff08;进程阻断&#xff09;。羊大师技术育儿实验…

关于数据仓库、数据湖、数据平台、数据中台和湖仓一体的概念和区别

我们谈论数据中台之前&#xff0c; 我们也听到过数据平台、数据仓库、数据湖、湖仓一体的相关概念&#xff0c;它们都与数据有关系&#xff0c;但他们和数据中台有什么样的区别&#xff0c; 下面我们将围绕数据平台、数据仓库、数据湖和数据中台的区别进行介绍。 一、相关概念…

什么是可重组机器人?

可重组机器人是一种具有高度灵活性和适应性的新型机器人系统&#xff0c;能够根据不同任务需求&#xff0c;快速改变自身结构和功能。下面我从概念、结构、特点、应用领域、发展趋势等方面&#xff0c;为你详细介绍&#xff1a; 概念&#xff1a;可重组机器人是由多个标准化、模…

4、docker compose

1、介绍 Docker Compose 是 Docker 官方提供的容器编排工具&#xff0c;用于简化多容器应用的开发、部署和管理。它通过声明式配置文件&#xff08;YAML格式&#xff09;定义容器化应用的服务、网络、存储等组件及其依赖关系&#xff0c;使用户能够通过单一命令快速启动、停止…

SQL里几种JOIN连接

数据信息&#xff1a; 员工表EMP 部门表DEPT 一、INNER JOIN&#xff08;内连接&#xff09; 作用&#xff1a;只返回两个表中完全匹配的行&#xff0c;相当于取交集。 场景&#xff1a;查询「有部门的员工信息」。 示例&#xff1a; SELECT 员工.姓名, 部门.部门名称 FR…

基于通义千问的儿童陪伴学习和成长的智能应用架构。

1.整体架构概览 我们的儿童聊天助手将采用典型的语音交互系统架构,结合大模型能力和外部知识库: 2. 技术方案分解 2.1. 前端应用/设备 选择: 移动App(iOS/Android)、Web应用,或者集成到智能音箱/平板等硬件设备中。技术栈: 移动App: React Native / Flutter (跨平台…

LVS-DR 负载均衡群集

目录 一、LVS-DR集群 1、LVS-DR 工作原理 2、数据包流向分析 3、LVS-DR 模式特点 二、直接路由模式&#xff08;LVS-DR&#xff09; 1、准备案例环境 2、配置负载调度器&#xff08;101&#xff09; &#xff08;1&#xff09;配置虚拟IP 地址&#xff08;VIP&#xff…

[Dify] 如何应对明道云API数据过长带来的Token超限问题

在集成明道云与大型语言模型(LLM)如ChatGPT或本地部署的Dify时,开发者经常会面临一个核心问题:API获取的数据太长,超出LLM支持的Token数限制,导致无法直接处理。本文将深入探讨这个问题的成因,并提供几种可行的解决方案,包括分段处理、外部知识库构建等策略。 明道云AP…

eNSP企业综合网络设计拓扑图

1.拓扑图 2.拓扑配置 此拓扑还有一些瑕疵&#xff0c;仅做参考和技术提升使用。 想要配置的可以关注下载 大型网络综合实验拓扑图&#xff08;eNSP&#xff09;资源-CSDN文库

BugKu Web渗透之备份是个好习惯

启动场景后&#xff0c;网页显示一段字符串。 看起来像md5值&#xff0c;但是又过长了。 步骤一&#xff1a;右键查看源代码&#xff0c;没有发现任何异常。 步骤二&#xff1a;使用dirsearch去查看是否有其他可疑文件。 在终端输入&#xff1a; dirsearch -u http://117.72.…

华为AP6050DN无线接入点瘦模式转胖模式

引言 华为AP6050DN是一款企业级商用的无线接入点。由于产品定位原因,其默认工作在瘦模式下,即须经AC统一控制和管理,是不能直接充当普通的无线路由器来使用的。 而本文的目的,就是让其能脱离AC的统一控制和管理,当作普通无线路由器来使用。 硬件准备 华为AP6050DN无线接…

十、【核心功能篇】项目与模块管理:前端页面开发与后端 API 联调实战

【核心功能篇】项目与模块管理&#xff1a;前端页面开发与后端 API 联调实战 前言准备工作第一部分&#xff1a;完善项目管理功能 (Project)1. 创建/编辑项目的表单对话框组件 第二部分&#xff1a;模块管理功能 (集成到项目详情页)1. 创建模块相关的 API 服务 (src/api/module…

【大模型/MCP】MCP简介

一句话总结 如果你打算让 LLM 像人一样“随手”调用脚本、数据库、搜索引擎或 CI/CD 流水线&#xff0c;而又不想为每个工具分别写 REST 插件或轮询接口&#xff0c;那么把它们包进 MCP 服务器是当前最省心、延迟最低、可复用最高的做法——正因如此 OpenAI、Google DeepMind、…

[Godot][游戏开发] 如何在 Godot 中配置 Android 环境(适配新版 Android Studio)

在使用 Godot 进行 Android 项目的开发与导出时&#xff0c;配置 Android 环境是一项必要步骤。随着 Android Studio 的更新&#xff08;特别是自 Arctic Fox 版本起&#xff09;&#xff0c;安装方式发生了变化&#xff0c;默认不再引导用户手动配置 SDK/JDK/NDK&#xff0c;而…

机器学习多分类逻辑回归和二分类神经网络实践

1、2-17 实现多分类逻辑回归 代码 # 2-17 实现多分类逻辑回归 import pandas as pd import numpy as np import matplotlib.pyplot as plt# 参数设置 iterations 5400 # 迭代次数 learning_rate 0.1 # 学习率 m_train 200 # 训练样本数量# 整数索引值转one-hot向量 def…

社交类网站设计:经典feed流系统架构详细设计(小红书微博等)

文章目录 一、关注服务1、粉丝、关注数架构设计&#xff08;1&#xff09;数据库实现方案1&#xff08;2&#xff09;数据库实现方案2&#xff08;3&#xff09;基于redis缓存优化&#xff08;4&#xff09;使用专用计数服务&#xff08;5&#xff09;近似计数&#xff08;牺牲…

RISC-V PMA、PMP机制深入分析

1 PMA PMA&#xff08;Physical Memory Attributes&#xff09;&#xff0c;物理内存属性&#xff0c;顾名思义就是用来设置物理内存属性的&#xff0c;但这里说“设置”&#xff0c;并不合理&#xff0c;因为一般情况下各存储的属性&#xff0c;在芯片设计时就固定了&#xf…

【NebulaGraph】查询案例(七)

【NebulaGraph】查询案例 七 1. 查询语句12. 查询语句23. 查询语句34. 查询语句4 1. 查询语句1 GO FROM "player100" OVER * YIELD type(edge) AS link, properties($$) AS properties,tostring(src(edge)) AS src,tostring(dst(edge)) AS dst, tags($$) AS tagLi…

从“刚性扩容”到“弹性供给”:移动充电服务重构配电网边际成本

随着新能源技术的快速发展&#xff0c;电动汽车的普及对传统配电网提出了新的挑战。传统的“刚性扩容”模式依赖基础设施的物理扩建&#xff0c;不仅投资成本高&#xff0c;且难以应对动态变化的电力需求。在此背景下&#xff0c;“弹性供给”理念逐渐兴起&#xff0c;特别是移…

Grafana-Gauge仪表盘

仪表盘是一种单值可视化。 可让您快速直观地查看某个值落在定义的或计算出的最小和最大范围内的位置。 通过重复选项&#xff0c;您可以显示多个仪表盘&#xff0c;每个对应不同的序列、列或行。 支持的数据格式 单值 数据集中只有一个值&#xff0c;会生成一个显示数值的…