浅谈Java并发
Java并发是比较难的知识点,难于对并发的理解。并发要从操作系统和硬件层面去理解,才会比较深入,而不单单是从编程语言的逻辑去理解。
首先对于并发要清楚的几点:
线程可能在任何时刻被切换。
计算机只对硬件指令保证原子性。
CPU有多级缓存,每个线程有自己的缓存空间。
第一点:
如果有共享数据或多线程判断逻辑,需要使用锁机制互斥其他线程的访问,避免逻辑错误。
第二点:
例如下面这个语句在编程语言里面只有一条语句,但编译成汇编语言会有三条硬件指令:(1)load i变量,(2)i变量自增1 (3)保存自增后的i变量。因此下面的语句不具有原子性。
i++;
第三点:
造成变量的可见性问题,单个线程读取并修改,修改的是自己线程缓存里面变量,对其他线程不可见,会造成可见性问题。
Java解决并发问题的一些关键字
1.synchronized关键字
监视器模式的锁,可以使代码块在线程之间互斥,持有锁的线程可以运行,没有持有锁的线程进入阻塞队列等待。synchronized是可重入锁,持有锁的线程可多次进入代码块。synchronized关键字修饰的代码块/方法内的代码具有原子性、可见性,可以解决上面的1、2、3问题。
2.volatile关键字
修饰变量,保证了变量的可见性,修饰的变量不再被CPU缓存,每次读取从内存中读取。每次写入变量也会立即刷新到内存,以保证变量对其他线程可见。还可以避免指令重排序,以及避免字分裂( 64位变量指令操作的分为两步)。但是这个不保证原子性。可解决上面的问题3。
3.final关键字
保证变量的不变性,如果一个变量是不变的,那么这个变量一定是线程安全的。
需要注意的是JVM为了性能优化,会对编译后的指令进行重排序,即在单个线程内是无影响的,但是对于多个线程来看重排序可能会导致预期之外的错误。volatile可以避免指令重排序。
在Java中的多线程是一一映射到操作系统的内核线程,每次线程切换都要经过内核态,对性能影响较大。
在Java中线程对应是的Thread类
Thread类通过接收一个Runnable接口的run方法来确定线程的执行逻辑。
Thread类通过start()方法来启动线程,里面执行的是定义好的run方法,start()方法只能执行一次,否则会报IllegalThreadStateException。
Thread thread = new Thread(() -> {
System.out.println(“hello world”);
});
thread.start();
Runnable接口是一个函数式接口,可以使用lambda表达式。
Thread类的其他方法介绍
1.sleep()方法
让目前正在执行的线程休眠,让CPU去执行其他的任务。
2.join()方法
线程合并,即当前线程会阻塞调用join()的线程,直到join的线程执行完成或超出设定的等待时间。
3.yield()方法
线程的yield(让步)操作的作用是让目前正在执行的线程放弃当前的执行,让出CPU的执行权限,使得CPU去执行其他的线程。
线程的状态
1.NEW状态
new Thread()创建了线程,但未调用start()启动线程。
2.RUNNABLE状态
Java把Ready(就绪)和Running(执行)两种状态合并为一种状态:RUNNABLE(可执行)状态(或者可运行状态)。调用了线程的start()实例方法后,线程就处于就绪状态。此线程获取到CPU时间片后,开始执行run()方法中的业务代码,线程处于执行状态。
3.BLOCKED状态处于BLOCKED(阻塞)状态的线程并不会占用CPU资源,以下情况会让线程进入阻塞状态:
(1)线程等待获取锁
(2)IO阻塞
4.WAITING状态
处于WAITING(无限期等待)状态的线程不会被分配CPU时间片,需要被其他线程显式地唤醒,才会进入就绪状态。
Object.wait()方法,对应的唤醒方式为:Object.notify()/Object.notifyAll()。
Thread.join()方法,对应的唤醒方式为:被合入的线程执行完毕。LockSupport.park()方法,对应的唤醒方式为:LockSupport.unpark(Thread)。
5.TIMED_WAITING状态
处于TIMED_WAITING(限时等待)状态的线程不会被分配CPU时间片,如果指定时间之内没有被唤醒,限时等待的线程会被系统自动唤醒,进入就绪状态。
6.TERMINATED状态线程结束任务之后,将会正常进入TERMINATED(死亡)状态;或者说在线程执行过程中发生了异常(而没有被处理),也会导致线程进入死亡状态。
公众号:
推荐阅读:
《Java并发编程实践》
浅谈Java并发的更多相关文章
- 浅谈Java并发编程系列(八)—— LockSupport原理剖析
LockSupport 用法简介 LockSupport 和 CAS 是Java并发包中很多并发工具控制机制的基础,它们底层其实都是依赖Unsafe实现. LockSupport是用来创建锁和其他同步 ...
- 浅谈Java的集合框架
浅谈Java的集合框架 一. 初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...
- 浅谈Java线程安全
浅谈Java线程安全 - - 2019-04-25 17:37:28 线程安全 Java中的线程安全 按照线程安全的安全程序由强至弱来排序,我们可以将Java语言中各种操作共享的数据分为以下五类 ...
- 朱晔的互联网架构实践心得S2E6:浅谈高并发架构设计的16招
朱晔的互联网架构实践心得S2E6:浅谈高并发架构设计的16招 概览 标题中的高并发架构设计是指设计一套比较合适的架构来应对请求.并发量很大的系统,使系统的稳定性.响应时间符合预期并且能在极端的情况下自 ...
- 浅谈Java回收对象的标记和对象的二次标记过程_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 一.对象的标记 1.什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈Java中的equals和==(转)
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...
- 浅谈Java中的对象和引用
浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...
- 浅谈Java中的equals和==
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...
- 浅谈JAVA集合框架
浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...
随机推荐
- NOI2014 洛谷P2114 起床困难综合征(位运算)
呃...这道题算是noi中比较简单的题吧...... 众所周知,位运算是个好东西,它就是对应的位进行运算,跟其他的位没有关系. 我们要选取一个m值使最后的攻击力最大,对于这个m,从高位开始枚举,判断该 ...
- SpringBoot实战派读书笔记---响应式编程
1.什么是WebFlux? WebFlux不需要Servlet API,在完全异步且无阻塞,并通过Reactor项目实现了Reactor Streams规范. WebFlux可以在资源有限的情况下提高 ...
- P1886 滑动窗口 /【模板】单调队列 方法记录
原题链接 滑动窗口 /[模板]单调队列 题目描述 有一个长为 \(n\) 的序列 \(a\),以及一个大小为 \(k\) 的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最 ...
- 现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
欢迎大家加入我的社区:http://t.csdn.cn/Q52km 社区中不定时发红包 文章目录 1.UML类图 2.源码: 3.优缺点分析 1.UML类图 2.源码: package com.bac ...
- IDEA中如何导入jar包、IDEA中找不到对应类改怎样解决?(详细图解过程)
今天突然心血来潮.用IDEA运行之前用eclipse编写的项目.发现遇到了一些bug,现在习惯了使用maven管理项目的依赖.一时间忘记了怎样将jar包导入项目中.特此记录一下 文章目录 1.未加入j ...
- Razor中RenderBoby的使用
1. RenderBody 在Razor引擎中没有了"母版页",取而代之的是叫做"布局"的页面(_Layout.cshtml)放在了共享视图文件夹中.在这个页面 ...
- ROS2时间同步(python)
最近1周一直研究ROS2的时间同步,翻越很多博客,很少有人使用ROS2进行时间同步的代码,无奈不断尝试与源码阅读,终于将其搞定, 为此,本博客将介绍基于python的ROS2的时间同步方法. 本博客内 ...
- 如何检查“lateinit”变量是否已初始化?
kotlin中经常会使用延迟初始化,如果要校验lateinit var 变量是否初始化.可以使用属性引用上的.isInitialized. 原文中是这样描述的:To check whether a l ...
- 17_Vue列表过滤_js模糊查询
列表过滤 需求分析 这里呢有张列表,假设这个列表有一百多条数据 当我在这个 搜索框当中 搜索 单个关键字的时候 (冬,周,伦),它能把带了这几个关键字的信息都给我罗列出来 === 跟数据库的 模糊查询 ...
- Substring 在BCL和CLR里面搞了啥
楔子 还是做点事情,不要那么散漫. 本文以简单的Substring(int startindex,int Length)函数为例,来递进下它在托管和非托管的一些行为. 以下均为个人理解,如有疏漏请指正 ...