当前位置: 首页 > news >正文

多线程二 多线程了解与使用

文章目录

  • synchronized 锁有两种
  • synchronized异常捕获
  • 主线程和子线程
  • volatile的作用
  • notify是随机启动等待线程中的一个

synchronized 锁有两种

  1. 类对象
  2. 类的实例

第一种:锁类对象,有两种方式,如下:

// 方法一:synchronized 修饰static方法
public static synchronized void test(){System.out.println(Thread.currentThread().getName()+" start ");try {TimeUnit.SECONDS.sleep(2);} catch (Exception e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" end ");
}
// 方法二:synchronized锁class对象
public void test2(){synchronized (getClass()) {try {TimeUnit.SECONDS.sleep(2);} catch (Exception e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" run ");}
}public static void main(String[] args) {TestThread10 t = new TestThread10();new Thread(()->TestThread10.test(),"线程 1 ").start();new Thread(()->t.test2(),"线程 2 ").start();
}

其结果如下:

结果1

在线程1,也就是先启动线程1且等线程1走完,才执行线程2;

锁类,就可以理解为,在类对象上加了一把锁,所有加锁的方法都需要等待上一把锁的释放才能执行

第二种:类的实例

只要对同一个实例对象加锁了,才能实现线程同步,如下:

public void test2(){synchronized (this) {try {TimeUnit.SECONDS.sleep(2);} catch (Exception e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" run ");}
}

synchronized异常捕获

使用synchronized的时候,出现异常一定要处理,不然他会自动释放锁
它的机制是手动加锁,自动释放锁。下面看一个例子,在异常的地方一定要处理异常,不然就会想下面代码中的线程1,会被释放掉。

private Integer c = 0;@Override
public void run() {count();
}private synchronized void count(){System.out.println(Thread.currentThread().getName()+" start。。。");while (true) {System.out.println(Thread.currentThread().getName()+" count="+c++);try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}if (c == 5) {int i = 1/0;}}}public static void main(String[] args) {TestThread3 t = new TestThread3();Thread t1 = new Thread(t, "线程 1");Thread t2 = new Thread(t, "线程 2");t1.start();t2.start();
}

图形2

主线程和子线程

线程分用户线程守护线程

main方法其实是一个主线程,在操作系统启动java.exe后,是开启了一个进程,然后进程启动main线程,main线程有启动其他线程。

  • 守护线程:和主线程一起结束(主线程结束,守护线程也结束)
  • 用户线程(非守护线程):但所有的用户线程结束,主线程结束
t2.setDaemon(true);
t2.start();

volatile的作用

可以看这位博主的博客:Java中Volatile关键字详解 - 郑斌blog - 博客园 (cnblogs.com)

它有两个功能:

  1. 线程间的可见性
  2. 防止指令重排序

注意:

可见性不代表原子性,它只是能够让其他线程能够实时查看到最新值,而其他操作,它不保证。

指令重排序,这个有点深奥,可以先暂时忽略

notify是随机启动等待线程中的一个

notify是随机启动等待线程中的一个,并且跟线程优先级无关,且 wait和notify方法要在同一把lock的情况下使用;还有一点是lock.wait 阻塞还后会把锁让出给需要的线程,然而,在其他线程执行完后,调用lock.notify(),唤醒等待的线程,但是在当前锁里的代码没执行完,不会释放掉锁。

简单场景模拟:

一个固定容量同步容器,拥有put和get方法,以及getCount方法,能够支持两个生产者线程以及10个消费者线程的阻塞调用。

public class TestThread8 {
private final LinkedList list = new LinkedList();private final int MAX = 10;private int count = 0;public synchronized void put(Object o) {while (list.size() == MAX) {try {// 在这里等待;的那个调用notify时会从这里继续执行this.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.add(o);count++;// 启动所有线程,包括生产者,随机的this.notifyAll();
}public synchronized void get() {while (list.size() == 0) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.removeLast();count--;this.notifyAll();
}public int getCount() {return list.size();
}public static void main(String[] args) {TestThread8 t = new TestThread8();for (int i = 0; i < 2; i++) {new Thread(() -> {int j = 0;while (true) {t.put(Thread.currentThread().getName() + " put " + t.getCount());System.out.println(Thread.currentThread().getName() + " put " + t.getCount());}}).start();}for (int i = 0; i < 10; i++) {new Thread(() -> {while (true) {t.get();System.out.println(Thread.currentThread().getName() + " get " + t.getCount());}}).start();}
}
}

相关文章:

多线程二 多线程了解与使用

文章目录synchronized 锁有两种synchronized异常捕获主线程和子线程volatile的作用notify是随机启动等待线程中的一个synchronized 锁有两种 类对象类的实例 第一种&#xff1a;锁类对象&#xff0c;有两种方式&#xff0c;如下&#xff1a; // 方法一&#xff1a;synchroni…...

嵌入式 Linux 的僵尸进程是什么?

目录 1、什么是僵尸进程&#xff1f; 2、僵尸进程的目的 3、怎么避免僵尸进程&#xff1f; 4、僵尸进程的处理方法 4.1 wait&#xff08;&#xff09;连接 4.2 waitpid&#xff08;&#xff09;函数 1、什么是僵尸进程&#xff1f; 首先内核会释放终止进程(调用了 exit …...

【刷题笔记】笔记一

1.自守数牛客链接解析&#xff1a;1.自守数的结尾肯定是 0&#xff0c;1&#xff0c;5&#xff0c;62.把数字转换为string类&#xff08;方便比较&#xff09;3.直接find在s2 里面 使用find查找另一个即可。#include <iostream> #include<string> using namespace …...

浏览器主页被hao123劫持的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...

华为OD机试题 - 热点网络统计(JavaScript)| 含代码编写思路

华为OD机试题 最近更新的博客使用说明本篇题解:热点网络统计题目输入输出描述示例一输入输出示例二输入输出Code解题思路华为OD其它语言版本最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华…...

IT项目经理的自我修养手册

在不断进步的时代&#xff0c;任何岗位职责都是一个责任、权力与义务的综合体&#xff0c;有多大的权力就应该承担多大的责任&#xff0c;有多大的权力和责任应该尽多大的义务&#xff0c;任何割裂开来的做法都会发生问题。那么作为IT项目经理的岗位职责&#xff0c;我大概列举…...

2023年软考中级电子商务设计师考什么?

首先&#xff0c;电子商务设计师属于软考中级&#xff0c;因此难度也不是特别大。但并不是说就完全没有难度&#xff0c;难度还是有的&#xff0c;像上午题一般把基本知识点掌握了&#xff0c;是没什么问题的&#xff0c;重点就在于下午题会比较难。 接下来我们来剖析一下考试…...

现在的00后太强了,几个问题差点给我问懵了

前言 我们公司刚入职一个00后小伙&#xff0c;今天在办公室交流了一下&#xff0c;他问我会不会自动化测试&#xff0c;我说懂一点&#xff0c;然后直接问了我几个自动化测试问题&#xff0c;差点直接给我问懵了&#xff01; 问题如下&#xff1a; 我们在制定自动化测试实施…...

$3 : 水​​​​​项目实战 - 水果库存系统

javase知识点复习&#xff1a; final关键字&#xff1a;http://t.csdn.cn/bvFgu 接口的定义&#xff0c;特性&#xff0c;实现&#xff0c;继承&#xff1a;http://t.csdn.cn/tbXl3 异常&#xff1a;http://t.csdn.cn/VlS0Z DAO的概念和角色&#xff08;设计理念&#xff09;&a…...

毕业设计 基于STM32单片机无线ZIGBEE智能大棚土壤湿度光照检测

基于STM32单片机无线ZIGBEE智能大棚土壤湿度光照检测1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STM32F103C8T6核心系统电路设计2.2 光敏采集电路设计2.3 温度采集电路设计3、部分代码展示3.1 读取DS18B20温度值3.2 定时器初始化1、项目简介 选题指导&#xff0c…...

华为OD机试真题Java实现【相对开音节】真题+解题思路+代码(20222023)

相对开音节 题目 相对开音节构成的结构为辅音+元音(aeiou)+辅音(r除外)+e,常见的单词有bike、cake等。 给定一个字符串,以空格为分隔符,反转每个单词中的字母,若单词中包含如数字等其他非字母时不进行反转。 反转后计算其中含有相对开音节结构的子串个数(连续的子串…...

【C++】30h速成C++从入门到精通(STL容器listvector)

listlist的介绍list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。list与…...

操作系统---存储管理

存储管理 操作系统将外存的文件调入到内存中&#xff0c;以便CPU调用&#xff0c;如果调用的内容不在内存中&#xff0c;则会产生缺页中断&#xff1b;产生缺页中断后&#xff0c;这事需要从外存调数据到内存中&#xff0c;然后CPU接着从断点继续调用内存中的数据&#xff1b;在…...

华为OD机试题 - 好朋友(JavaScript)| 含思路

华为OD机试题 最近更新的博客使用说明本篇题解:好朋友题目输入输出示例一输入输出说明示例二输入输出说明Code解题思路华为OD其它语言版本最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典...

socket本地多进程通信基本使用方法和示例

目录 前言&#xff1a; socket是什么 socket基本原理框图 socket基本函数 1 socket() 函数 2 bind()函数 3 connect()函数 4 listen() 函数 5 accept() 函数 6 read() write() send() recv()函数 7 close()函数 8 字节序转换&#xff08;hton&#xff09; 示例代码 …...

Python 算法交易实验51 Step2 Signals 信号生成

说明 不可不读书 先从经典的一些超简单信号开始 使用移动平均指标SMA(算术&#xff09; 给出了信号的产生方法&#xff0c;还有一些测算结果&#xff0c;反正看起来都是盈利的 首先使用离线方法实验一组结果&#xff0c;然后就使用ADBS来进行类似的处理。 内容 1 原理分析…...

app上架专用软著认证电子版权在主流应用商店的使用说明2023年最新版

软著认证电子版权在主流应用商店的使用说明 目录 一、 华为应用商店 二、 腾讯应用宝 三、 小米开放平台 小米应用提交&#xff1a; 小米游戏提交&#xff1a; 四、 OPPO开放平台 OPPO应用提交: OPPO游戏&#xff08;App&#xff09;提交: OPPO小游戏&#xff08;快应…...

[Mybatis2]Mapper代理开发

文章目录 问题情境 代理开发 遵循的三条原则 1.定义与SQL映射文件同名的Mapper接口&#xff0c;并且将Mapper接口和SQL映射文件放置在同一目录下 2.设置SQL映射文件的namespace属性为Mapper接口的全限定名 3.在Mapper接口中定义方法&#xff0c;方法名就是SQL映射文件中sql…...

第十一届蓝桥杯大赛青少组国赛Python真题2

第十一届蓝桥杯大赛青少组Python 真题 第二题 提示信息&#xff1a; 杨辉三角形&#xff0c;是二项式系数在三角形中的一种几何排列。中国南宋数学家杨辉在 1261 年所著的《详 解九章算法》一书有明确记载。欧洲数学家帕斯卡在 1654 年发现这一规律&#xff0c;所以又叫做帕斯卡…...

创建springboot项目文件报红

目录 一、遇到问题 二、出现这个问题的原因 三、解决办法 三种方法 四、操作步骤 一、遇到问题 创建springboot项目的时候&#xff0c;会发现一些重要文件都变成红色了&#xff0c;但是不影响程序的运行。只是看起来会有点不舒服。 二、出现这个问题的原因 因为这个spr…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...