JAVA线程及简单同步实现的原理解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: JAVA线程及简单同步实现的原理解析线程一、内容简介:  本文主要讲述计算机中有关线程的相关内容,以及JAVA中关于线程的基础知识点,为以后的深入学习做铺垫。如果你已经是高手了,那么这篇文章并不适合你。

JAVA线程及简单同步实现的原理解析
线程
一、内容简介:
  本文主要讲述计算机中有关线程的相关内容,以及JAVA中关于线程的基础知识点,为以后的深入学习做铺垫。如果你已经是高手了,那么这篇文章并不适合你。

二、随笔正文:
1、计算机系统组成
  计算机系统由计算机硬件系统和软件系统组成。我们今天要说的线程和硬件系统中的cpu中央处理器,及软件系统中的操作系统,进程等有比较紧密的联系。操作系统是软件中比较特殊的存在,与硬件系统直接交互,其他程序(软件)运行在操作系统之上。

2、cpu简单说明
  硬件系统中特别重要的一项就是处理器CPU,与我们所说的线程有非常紧密的联系。cpu中有几项参数,以及如何查看该信息,在下文逐一说明:

块数:民用pc机,基本都是一块物理cpu,每块主板上只能装一块cpu。

核心数:也就是单块物理cpu是由几组处理芯片组,组成的。4核心 8核心等。

线程数:老款cpu都是单线程的,及一组芯片组只能运行一个线程。现款因特尔cpu大多支持超线程技术可支持多个逻辑线程。但是需要操作系统及相关编程语言的支持,JAVA相较C++在多线程方面能表现的更出色。

主频:单位GHZ(hz赫兹 每秒的周期性变动重复次数)在计算机中即高低电平变化一次,可以产生两个不同的电信号0、1。以我的CPU I5-4200M 2.5GHZ 举例,及cpu可以每秒完成25亿次震荡! 也就是说主频越高理论上计算能力越强,处理计算机指令越快。但是并不代表计算机整体运算速度约高,这点通常满足水桶效应,而cpu一直稳居长板地位。

缓存:cpu内置缓存,很小通常为几Mb至十几Mb,和cpu交互更频繁,速度也远高于普通运行内存,提高cpu处理能力的有效手段。

查看cpu参数指令:

DOS命令
3、关系梳理
  操作系统,程序,进程,线程之间的关系梳理、

  程序:是计算机上的静态代码,指令文件集合,是静态的存在。比如:QQ,LOL等

  进程:程序的执行实体(过程),持有及分配资源的主体。chrome.ext,QQ.exe等执行进程。

  线程:是进程中的劳动力,由进程创建,完成指定任务后结束。

  关系:

    操作系统 1 ——> n 程序 1 ——> n 进程 1 ——> n 线程

     平台       集合     资源     干活的

  普通进程创建线程去完成指定的计算机指令,这个时候需要调用系统资源如cpu进行运算,但是用户线程并不能直接驱动硬件,而是通过操作系统去统一分配、控制硬件的使用。

4、进程、线程基本状态

  五个基本状态,创建和终止不说了。计算机中的线程创建之后会进入就绪状态,当cpu为此线程分配时间片时,线程由就绪转为执行状态,开始干活,当时间片结束时回到就绪状态等待下次获取时间片,循环直到任务完成,当任务完成时,线程终止(死亡)。若在执行过程中遇到耗时操作比如IO或者JAVA中的线程休眠等,会进入阻塞状态,阻塞结束会进入就绪状态继续排队等待被分配时间片。

5、JAVA中的线程
  java中提供了两种方式去创建线程,继承类和实现接口。由于java中单继承机制的限制,大多数情况下使用实现Runnable接口的形式创建线程。

1 、继承Thread类
继承Thread类
2、实现Runnable接口
实现Runnable接口
3、线程的常用方法
复制代码
1 start()
2 //启动线程,调用run方法
3 sleep()
4 //线程休眠,进入阻塞状态,让出时间片,但不会让出锁
5 Thread.currentThread()
6 //获取当前执行线程
7 wait/notify()
8 //仅能存在synchronized代码块中,wait线程休息,让出时间片,进入等待状态,notify()唤醒该线程;该方法存在重载
9 join()
10 //等待此线程执行完毕
11 setDaemon()
12 //设置守护线程,守护线程是服务线程,当用户线程结束,守护线程自动结束
13 yield()
14 //主动让出时间片给其他线程
15 interrupt()
16 //中断线程,不推荐
17 get/setId()
18 //设置获取线程id
19 get/setName()
20 //设置获取线程名
21 get/setPriority()
22 //设置获取线程优先级,理论上优先级越高,获取时间片的概率越大,默认是5最高10最小1
复制代码
4、JAVA中的线程状态图

5、线程练习
简单模拟多线程购票业务

售票业务
  在不做任何控制的情况下,出错的几率很小,我反复测试几次,结果基本都正确!分析原因:业务本身相对简单,没有耗时操作,每个时间片基本能保证线程将本次任务执行完毕!也就是将票数减一并打印内容。

  为了模拟在售票前双方的问询阶段及付款阶段的等待,在售票前(后)加入Thread.sleep(ms) 模拟耗时操作。

加入线程休眠
  改动后系统出现bug同一张票被售出了多次,并且可能将票卖出负数。究其原因:线程之间的数据争用问题,我们将引入JAVA内存模型进行分析(图片来自网络侵删)

  首先我们需要知道几个概念,如下:

  共享变量:主内存中存在被多个线程同时用到的变量,在多个线程中存在相应副本变量。

  可见性:线程对共享变量的值进行修改,能否被其他线程可见。

  变量访问规则:   1、线程对共享变量的操作只能在自己工作内存中的副本。

            2、工作内存中的变量变化需要通过主内存传递。

6、实现同步
  实现同步即实现共享变量可见性,工作内存1 ——> 主内存 ——>工作内存2,在数据传递的两个环节中出现问题都会对同步造成影响,从而影响执行结果。

  synchronized实现同步

  synchronized 可以实现指令的原子性,及共享变量的可见性。

  原子性:synchronize修饰的方法或者代码块会获取互斥锁,保证同一时间只能有一个对象访问该方法或代码块,将其作为一个整体,保证了原子性。

​   可见性:加锁后,先清空工作内存,同步主内存中的共享变量。解锁前,先将工作内存中的变量同步到主内存,再释放锁。

  所以结合上述例子,为sellTickets()方法加锁即可实现同步;或者对核心代码片段加锁;

复制代码
private synchronized boolean sellTickets() { //… 省略中间代码
}
  //或者如下实现
  
synchronized(this){

   //this指的是调用sellTickets()的对象

}
复制代码
7、volatile关键字
  共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

  原理:被volatile修饰的变量所生成汇编代码时有lock前缀,生成"内存屏障"。

    1)保证了不同线程对这个变量进行操作时的可见性,即工作内存中的变量值在修改后会被立即同步到主内存中;

    2)并且使其他线程中的缓存无效,这样当其他线程在访问共享变量时就必须取主内存中获取;

    3)禁止进行指令重排序;

  综上所述,volatile可以保证可见性,但不能保证原子性;

  举例分析:

复制代码
volatile int number = 0 ;
number ++ ;
/*

操作可以解析成三步:  1.获取number中的值 
                  2.计算加1操作 
                  3.number = 0 + 1; 
在一个时间片中,虽然volatile修饰的number一定会被立即同步到主内存中,但不能保证完整执行这三步,所以不能保证++操作的原子性 。

*/
复制代码
三、总结说明:
  首先感谢各位能看到最后,对本文内容如果存在疑问,欢迎留言交流,若存在错误,也还望斧正!我将不定期对文章进行修改和调整,如发现错误一定及时改正以免误人子弟!
原文地址https://www.cnblogs.com/lijizhi/p/10775748.html

相关文章
|
4天前
|
存储 Java 计算机视觉
Java二维数组的使用技巧与实例解析
本文详细介绍了Java中二维数组的使用方法
27 15
|
23天前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
110 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
4天前
|
算法 搜索推荐 Java
【潜意识Java】深度解析黑马项目《苍穹外卖》与蓝桥杯算法的结合问题
本文探讨了如何将算法学习与实际项目相结合,以提升编程竞赛中的解题能力。通过《苍穹外卖》项目,介绍了订单配送路径规划(基于动态规划解决旅行商问题)和商品推荐系统(基于贪心算法)。这些实例不仅展示了算法在实际业务中的应用,还帮助读者更好地准备蓝桥杯等编程竞赛。结合具体代码实现和解析,文章详细说明了如何运用算法优化项目功能,提高解决问题的能力。
39 6
|
4天前
|
存储 算法 搜索推荐
【潜意识Java】期末考试可能考的高质量大题及答案解析
Java 期末考试大题整理:设计一个学生信息管理系统,涵盖面向对象编程、集合类、文件操作、异常处理和多线程等知识点。系统功能包括添加、查询、删除、显示所有学生信息、按成绩排序及文件存储。通过本题,考生可以巩固 Java 基础知识并掌握综合应用技能。代码解析详细,适合复习备考。
14 4
|
10天前
|
SQL Java 数据库连接
如何在 Java 代码中使用 JSqlParser 解析复杂的 SQL 语句?
大家好,我是 V 哥。JSqlParser 是一个用于解析 SQL 语句的 Java 库,可将 SQL 解析为 Java 对象树,支持多种 SQL 类型(如 `SELECT`、`INSERT` 等)。它适用于 SQL 分析、修改、生成和验证等场景。通过 Maven 或 Gradle 安装后,可以方便地在 Java 代码中使用。
113 11
|
4天前
|
存储 Java
【潜意识Java】期末考试可能考的选择题(附带答案解析)
本文整理了 Java 期末考试中常见的选择题,涵盖数据类型、控制结构、面向对象编程、集合框架、异常处理、方法、流程控制和字符串等知识点。每道题目附有详细解析,帮助考生巩固基础,加深理解。通过这些练习,考生可以更好地准备考试,掌握 Java 的核心概念和语法。
13 1
|
9天前
|
存储 分布式计算 Hadoop
基于Java的Hadoop文件处理系统:高效分布式数据解析与存储
本文介绍了如何借鉴Hadoop的设计思想,使用Java实现其核心功能MapReduce,解决海量数据处理问题。通过类比图书馆管理系统,详细解释了Hadoop的两大组件:HDFS(分布式文件系统)和MapReduce(分布式计算模型)。具体实现了单词统计任务,并扩展支持CSV和JSON格式的数据解析。为了提升性能,引入了Combiner减少中间数据传输,以及自定义Partitioner解决数据倾斜问题。最后总结了Hadoop在大数据处理中的重要性,鼓励Java开发者学习Hadoop以拓展技术边界。
34 7
|
18天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
80 17
|
9天前
|
Java Linux 调度
硬核揭秘:线程与进程的底层原理,面试高分必备!
嘿,大家好!我是小米,29岁的技术爱好者。今天来聊聊线程和进程的区别。进程是操作系统中运行的程序实例,有独立内存空间;线程是进程内的最小执行单元,共享内存。创建进程开销大但更安全,线程轻量高效但易引发数据竞争。面试时可强调:进程是资源分配单位,线程是CPU调度单位。根据不同场景选择合适的并发模型,如高并发用线程池。希望这篇文章能帮你更好地理解并回答面试中的相关问题,祝你早日拿下心仪的offer!
26 6
|
14天前
|
缓存 安全 算法
Java 多线程 面试题
Java 多线程 相关基础面试题

热门文章

最新文章

推荐镜像

更多