【JavaSE线程知识总结】
多线程
- 一.创建线程
- 1.多线程创建方式一(Thread)
- 2.多线程创键方式二(Runnable)
- 3.线程创建方式三
- 二.线程安全问题
- 解决办法
- 1.使用同步代码块synchornized
- 2 .使用Lock解决线程安全问题
- 三.总结
- 线程就是程序内部的一条执行流程
一.创建线程
常用的方法
- Thread.currentThread(): 获取当前线程
- Thread.getName(): 获取当前线程的名称
- Thread.setName(): 设置当前线程的名称
- Thread.yield(): 礼让当前正在执行的线程
- Thread.sleep(long millis): 让当前线程暂停millis毫秒
- Thread.interrupt(): 中断当前线程
- Thread.isInterrupted(): 判断当前线程是否被中断
- Thread.currentThread().interrupt(): 中断当前线程
- Thread.join(): 插队,调用这个方法的线程先执行完毕
- Thread.sleep()睡眠
1.多线程创建方式一(Thread)
- 定义一个子类MyThread继承Thread,重写run方法
- 创建Mythread类的对象
- 通过对象调用start方法启动线程,线程开启后,会自动调用线程对象的run方法执行
- JVM会自动开启一个线程,执行main方法,称为主线程
- 主线程中开启了其他线程称为子线程
- 开启了子线程后,子线程会跟我们的主线程争抢资源,谁抢到了谁就先执行,执行一小会用释放,再重新抢占资源
优点: 创建线程简单
缺点: 扩展性不强,不能返回线程执行结果


2.多线程创键方式二(Runnable)
- 定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法
- 创建MyRunnable任务对象
- 把MyRunnable对象交给Thread处理
- 调用start()方法启动线程
优点
线程任务与线程对象分离,可以让同一线程执行不同的任务
缺点
需要多一个Runnable对象
不能返回线程结果



3.线程创建方式三
- 实现callable<返回值类型>接口,重写call方法
- callable接口在实现的时候需要指定泛型,用来确定返回值的数据类型
- 创建FutureTask对象,构造方法中需要传入callable接口实现类对象
- FutureTask()中提供了一个get(),它是一个阻塞的方法,他会阻塞线程一直从Futurue对象中去获取返回的结果,如果没有获取到会一致阻塞等待
- 创建Thread对象,构造方法中传入futureTask对象
- 调用start()方法启动线程
- 调用get()方法的时候会有异常(最好分开进行try… catch异常捕获,因为当有一条线程出现异常的时候,不会影响到其他线程的返回结果,)
package com.dream.Thread;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class ThreadDemo03 {public static void main(String[] args) {//1.线程创建的方式三: 实现callable接口,重写call方法//callable接口在实现的时候需要指定泛型,用来确定返回值的数据类型//2.创建callable接口实现类的对象MyThread3 myThread3 = new MyThread3(100);//3.创建FutureTask对象,构造方法中需要传入callable接口实现类对象FutureTask<String> futureTask = new FutureTask<>(myThread3);//futureTask对象是线程任务对象,他的get方法可以在线程运行结束后,获取线程执行结果//4.创建Thread对象,构造方法中传入futureTask对象Thread t = new Thread(futureTask);//5.启动线程t.start();MyThread3 myThread3_2 = new MyThread3(200);FutureTask<String> futureTask_2 = new FutureTask<>(myThread3_2);Thread t2 = new Thread(futureTask_2);t2.start();//6.获取线程执行结果(最好分开进行try... catch异常捕获,因为当有一条线程出现异常的时候,不会影响到其他线程的返回结果,)try {String result = futureTask.get();System.out.println(result);} catch (Exception e) {e.printStackTrace();}try {String result_2 = futureTask_2.get();System.out.println(result_2);} catch (Exception e) {e.printStackTrace();}}
}class MyThread3 implements Callable<String> {private int n;public MyThread3(int n) {this.n = n;}@Overridepublic String call() throws Exception {//计算1-n的和返回int sum = 0;for (int i = 1; i <= n; i++) {sum += i;}return "1-" + n + "的和为:" + sum;}
}
二.线程安全问题
- 存在多个线程在同时执行
- 同时访问一个共享资源
- 同时对共享资源做操作
比如两个人访问同一个银行账户,就会出现线程安全问题
package com.dream.threadsafe;public class MyRunnable implements Runnable {private Account account = new Account();@Overridepublic void run() {if (account.getBalance() >= 100000) {account.withdraw(account, 100000);} else {System.out.println("余额不足,取款失败");}}
}/*** 模拟取款*/class Account {private int balance = 100000;// 余额public int getBalance() {return balance;}public void withdraw(Account acc, int amount) {System.out.println(Thread.currentThread().getName() + "正在取款" + amount);balance -= amount;System.out.println(Thread.currentThread().getName() + "取款成功,余额为" + balance);}
}
启动线程
public class Test {public static void main(String[] args) {MyRunnable mr = new MyRunnable();Thread t1 = new Thread(mr, "小明");Thread t2 = new Thread(mr, "小红");t1.start();t2.start();}
}
解决办法
1.使用同步代码块synchornized
- 同步锁:我们传入的参数要是唯一的对象,
- 但是不要直接使用字符串作为锁对象,因为会导致其它无关线程不能同步线程
- 如果同步锁对象是在实例方法内部,那么锁对象就是this
- 每次抢占到资源都会判断当前锁是否是开启的,开启了就进入执行,关闭则等待
- 如果同步锁对象是在静态方法内部,那么锁对象就是 类名.class
- 也可以直接加在方法的修饰符后面,构成同步方法


2 .使用Lock解决线程安全问题
- Lock是一个接口,需要创建它的实现类对象ReentranLock()是Lock接口的实现类
- 相较于synchronized锁,Lock会更加的灵活
- 他俩都属于重量级锁
private final Lock lk = new ReentrantLock();
public void withdraw(Account acc, double money) {lk.lock();//上锁try {if (this.money >= money) {//余额足够,取款System.out.println(Thread.currentThread().getName() + "取款成功");//更新余额this.money -= money; //System.out.println(acc.getCardId() + "余额为:" + this.money);} else {System.out.println("余额不足");System.out.println(Thread.currentThread().getName() + "取款失败");}} finally {lk.unlock();//解锁}}
三.总结
本章主要讲解了线程几种线程的创建方式,线程安全问题出现的场景,以及线程安全的解决方式
相关文章:
【JavaSE线程知识总结】
多线程 一.创建线程1.多线程创建方式一(Thread)2.多线程创键方式二(Runnable)3.线程创建方式三 二.线程安全问题解决办法1.使用同步代码块synchornized 2 .使用Lock解决线程安全问题 三.总结 线程就是程序内部的一条执行流程 一.创建线程 常用的方法 Thread.currentThread()…...
FreeRTOS内存管理
1. 为什么要自己实现内存管理 对于内核对象,可以使用时分配,不使用时释放C语音的库函数不适应与FreeRTOS: 实现过于复杂,占用空间大并非线程安全的运行不确定性:每次运算时间不确定内存碎片化不太编译器配置不同调试难 2. 堆栈…...
利用服务工作线程serviceWorker缓存静态文件css,html,js,图片等的方法,以及更新和删除及版本控制
Service Worker 是一种运行在浏览器背后的独立线程,可以用来处理推送通知、后台同步、缓存等任务。以下是使用 Service Worker 来缓存图片的一个基本示例: 1、注册 Service Worker: 首先,你需要在你的 JavaScript 文件中注册 Service Worker。…...
MuMu模拟器安卓12安装Xposed 框架
MuMu模拟器安卓12安装Xposed 框架 当开启代理后,客户端会对代理服务器证书与自身内置证书展开检测,只要检测出两者存在不一致的情况,客户端就会拒绝连接。正是这个原因,才致使我们既没有网络,又抓不到数据包。 解决方式: 通过xposed框架和trustmealready禁掉app里面校验…...
高级数据结构——hash表与布隆过滤器
文章目录 hash表与布隆过滤器1. hash函数2. 选择hash函数3. 散列冲突3.1 负载因子3.2 冲突解决3. STL中的散列表 4. 布隆过滤器4.1 背景1. 应用场景2. 常见的处理场景: 4.2 布隆过滤器构成4.3 原理4.4 应用分析4.5 要点 5. 分布式一致性hash5.1 缓存失效问题 6. 大数…...
【网络】什么是交换机?switch
交换机(Switch)意为“开关”,是一种用于电(光)信号转发的网络设备。以下是关于交换机的详细解释: 一、交换机的基本定义 功能:交换机能为接入交换机的任意两个网络节点提供独享的电信号通路&am…...
软件测试 —— 自动化基础
目录 前言 一、Web 自动化测试 1.什么是 Web 自动化测试 2.驱动 3.安装驱动管理 二、Selenium 1.简单 web 自动化测试示例 2.工作原理 三、元素定位 1.cssSelector 2.XPath 四、操作测试对象 1.点击/提交对象 2.模拟按键输入 3.清除文本内容 4.获取文本信息 5.…...
深入解析 OpenHarmony 构建系统-4-OHOSLoader类
在OpenHarmony操作系统构建过程中,OHOSLoader类扮演着至关重要的角色。这个类负责加载和解析构建配置,生成必要的构建文件,并确保构建过程的顺利进行。本文将深入分析OHOSLoader类的实现细节,揭示其如何管理构建配置,并…...
【Android、IOS、Flutter、鸿蒙、ReactNative 】实现 MVP 架构
Android Studio 版本 Android Java MVP 模式 参考 模型层 model public class User {private String email;private String password;public User(String email, String password) {this.email = email;this.password = password;}public String getEmail() {return email;}…...
排序算法(基础)大全
一、排序算法的作用: 排序算法的主要作用是将一组数据按照特定的顺序进行排列,使得数据更加有序和有组织。 1. 查找效率:通过将数据进行排序,可以提高查找算法的效率。在有序的数据中,可以使用更加高效的查找算法&…...
Pytest从入门到精通
一、pytest单元测试框架 (1)什么是单元测试框架 单元测试是指在软件开发当中,针对软件的最小单位(函数,方法)进行正确性的检查测试。 (2)单元测试框架 java : junit和testng python : unittest和pytest (3)单元测试框架主要做什么? 1.测试发现:从多个文件里面去找到我们测试…...
《C++ 实现生成多个弹窗程序》
《C 实现生成多个弹窗程序》 在 C 编程中,我们可以利用特定的系统函数来创建弹窗,实现向用户展示信息等功能。当需要生成多个弹窗时,我们可以通过循环结构等方式来达成这一目的。 一、所需头文件及函数介绍 在 Windows 操作系统环境下&#…...
react 中 useRef Hook 作用
useRef是一个非常实用的钩子函数 一、访问和操作 DOM 元素 1. 获取 DOM 元素引用 1.1 基本原理 通过 useRef 我们可以直接操作 DOM 元素 1.2 代码示例 import React, { useRef, useEffect } from "react";const InputFocusComponent () > {const inputRef …...
Scala-键盘输入(StdIn)-用法详解
Scala 在 Scala 中,进行 键盘输入 主要通过 scala.io.StdIn 包来实现。 StdIn 提供了几个方法,用于从用户的键盘输入中读取不同类型的数据,如字符串、整数、浮点数等。 常用的输入方法有 readLine()、readInt()、readDouble()、readShort(…...
力扣(LeetCode)283. 移动零(Java)
White graces:个人主页 🙉专栏推荐:Java入门知识🙉 🐹今日诗词:雾失楼台,月迷津渡🐹 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主…...
ESP32C3单片机使用笔记---烧录MicroPython
使用MicroPython在ESP32C3单片机上编程,首先需要将MicroPython运行环境烧录到ESP32C3的Flash中去,步骤如下: 1.下载esptool烧录工具,下载地址: https://github.com/espressif/esptool 直接使用git clone git clone…...
Matter1.4重磅来袭,智能家居进入“互联”新纪元
近日,连接标准联盟(CSA)正式宣布推出最新的Matter1.4标准版本,并更新了一系列“史诗级”的增强功能,旨在提升现有智能家居之间的互操作性与兼容性,为智能家居用户带来更流畅的使用体验。 华普微,…...
tdengine学习笔记
官方文档:用 Docker 快速体验 TDengine | TDengine 文档 | 涛思数据 整体架构 TDENGINE是分布式,高可靠,支持水平扩展的架构设计 TDengine分布式架构的逻辑结构图如下 一个完整的 TDengine 系统是运行在一到多个物理节点上的,包含…...
机器学习-36-对ML的思考之机器学习研究的初衷及科学研究的期望
文章目录 1 机器学习最初的样子1.1 知识工程诞生(专家系统)1.2 知识工程高潮期1.3 专家系统的瓶颈(知识获取)1.4 机器学习研究的初衷2 科学研究对机器学习的期望2.1 面向科学研究的机器学习轮廓2.2 机器学习及其应用研讨会2.3 智能信息处理系列研讨会2.4 机器学习对科学研究的重…...
Linux 进程信号的产生
目录 0.前言 1. 通过终端按键产生信号 1.1 CtrlC:发送 SIGINT 信号 1.2 Ctrl\:发送 SIGQUIT 信号 1.3 CtrlZ:发送 SIGTSTP 信号 2.调用系统命令向进程发信号 3.使用函数产生信号 3.1 kill 函数 3.2 raise 函数 3.3 abort 函数 4.由软件条件产…...
从零构建:基于FreeRTOS与LVGL的低功耗智能手表实战指南
1. 项目背景与核心目标 第一次接触智能手表开发是在三年前,当时市面上开源的方案要么功能简陋,要么功耗高得离谱。作为一个嵌入式老鸟,我决定自己动手搞一套真正可用的低功耗方案。经过多次迭代,最终选择了FreeRTOSLVGL这个黄金组…...
三维点云到二维图像投影的实战指南:从原理到代码实现
1. 三维点云投影二维图像的核心原理 第一次接触三维点云投影时,我也被各种坐标系转换绕得头晕。后来发现只要抓住一个核心:三维到二维的投影本质上是坐标系转换的接力赛。想象你拿着手机拍照,物体从现实世界到手机屏幕的旅程,就是…...
centos7安装MySQL8.4手册
目录前言一、首先更新插件,并查看当前系统版本二、安装步骤--在线安装1、创建mysql目录2、安装rpm包3、安装 mysql-community-server4、启动MySQL服务5、查看MySQL状态6、设置开机自启动三、查看默认密码四、登录mysql五、修改密码六、开启远程访问1. 修改 MySQL 配…...
告别数据丢失!GD32串口DMA双缓冲+内存对齐配置避坑指南
GD32串口DMA双缓冲与内存对齐实战:工业级数据零丢失方案 在工业自动化、高速数据采集等场景中,串口通信的稳定性和效率直接关系到整个系统的可靠性。当波特率提升到921600甚至更高时,传统的轮询或中断方式往往难以应对持续的数据流࿰…...
2026搜索量暴涨!这几款配音软件火到刷屏
如果你最近刷短视频,一定注意到了——声音比画面更抓人。从悬疑解说的低沉旁白,到小说推文的多角色演绎,再到带货视频的情绪播报,一条爆款视频的背后,往往藏着一款好用的配音软件。2026年,AI配音市场迎来爆…...
Bitahub算力上新 RTX3080 10G重磅登场
针对当前 AI 开发与科研场景中算力成本高、配置复杂的痛点,Bitahub 平台推出了 RTX3080 10G 显卡算力服务。该显卡具备 10GB 显存,能够满足模型训练、推理等多场景算力需求,同时平台定价极具竞争力:单卡低至 0.82 元 / 小时&#…...
2026年03月GESPC++二级真题解析(含视频)
视频讲解:GESP2026年3月二级C真题讲解 一、单选题 第1题 解析: 答案B,ACD选项都是向机器人输入信息,是输入设备 第2题 解析: 答案D,判断是 “ 菱形框 ” 第3题 解析: 答案D,变…...
三三复制系统模式介绍
三三复制系统模式介绍:从底层逻辑到合规落地在社交电商与团队裂变领域,三三复制系统凭借其低门槛、高稳定性的特点,成为企业实现用户快速增长与业绩倍增的重要工具。不同于传统多级分销的复杂层级,三三复制系统以“三”为核心基数…...
当你能证明你的代码能带来流量时,你就永远不会被视为“垃圾”。
在商业世界里,代码本身没有价值,代码产生的结果才有价值。 如果你写的代码逻辑完美、架构优雅、注释清晰,但用户不用、业务不增长,那它在老板眼里就是“成本”,甚至是“垃圾”。如果你写的代码哪怕有些粗糙、用了“笨办…...
MxRadioRF2xx库:ARM Mbed平台RF2xx射频驱动开发指南
1. MxRadioRF2xx 库概述 MxRadioRF2xx 是一个专为 ARM Mbed OS 平台设计的 Atmel(现 Microchip)RF2xx 系列射频收发器驱动库。该库并非对底层寄存器操作的简单封装,而是面向嵌入式无线应用开发者的工程化抽象层,其核心目标是&…...
