网站首页 > 博客文章 正文
前言
Java天生具有对多线程和并发强大的支持,这使得编写并发应用程序变得非常容易。 但通常情况下,多线程应用程序在调试过程、排除故障的时候都比较困难。 从我的并发应用程序的经验来看,大多数问题都是在大规模运行时发现的。因此,我们在开发的时候一定要了解它的原理,防范于未然。大家肯定对Java并发编程有点望而生畏的感觉。其实不是很难。看完这篇文章你心中应该有一个明白的概念的。我相信。
Java并发
我们来看这第一个例子:
public class Foo {
private int x;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
}
我们问题来了,这个类是线程安全的么?答案显而易见,肯定不是的。而我们要怎么做才能保证它线程是安全的么?大家一定会想到是在get和set方法前面加上synchronized关键词。
synchronized
大家估计或多或少有见过这个关键字,但是具体的玩法估计没有很深刻的了解。
当一个线程调用synchronized方法或代码块时,它会尝试获取一个内部锁(监视器)。一旦线程获得锁定,其他线程将阻塞,直到锁定被释放。
这看起来是挺好的解决方案! 但synchronized有一些缺点:
线程饿死:synchronized并不保证公平。 这意味着如果有很多线程竞争获得锁定,那么有可能一些线程没有机会继续,这意味着进入了闲置状态且完全不会被调用到(我们程之为饿死的状态)。
死锁:从其他同步代码调用同步代码可能导致死锁。
吞吐量较低:使用synchronized意味着只有一个线程在特定的对象上执行。 在很多情况下,这是没有必要的,因为仅在写入时锁定对变量的访问就足够了,如果当前所有线程正在读取(并发读取),则不需要锁定变量。
从上面几点来看,我们就知道synchronized对于线程安全是有利的,但并不是最佳的。如果胡乱的使用synchronized关键字的话会大大的影响程序的运行效率或者运行结果。
Volatile
另一个解决并发的方式就是使用volatile,上面的代码就是在private int x;改成private volatile int x;
volatile能够保证程序的:
可见性:如果一个线程改变了一个变量的值,那么这个改变对于读取该变量的其他线程立即可见。 这是通过不允许编译器或JVM在CPU寄存器中分配这些变量来保证的。 对volatile变量的任何写操作都会立即刷新到主内存中,并且从主内存中读取它。 这意味着会有一些性能损失,但是从并发性的角度来看,这是一个很好的事情。
不允许指令排序:有时为了性能优化,JVM重新排序指令。 访问volatile变量时不允许这样做。 对volatile变量的访问不会通过访问其他volatile变量进行重新排序,也不能访问其他正常字段。 这使得对其周围的非volatile字段的写入立即可见于其他线程。
然而volatile也不是万能药,记住在下面场景中千万不要用volatile:类似于 ++, --, 等。这是因为这些操作会转化成多个读写指令。
在一个多线程程序中,这样的操作应该是原子的,volatile不能保证。 Java SE带有一系列的原子类,如AtomicInteger,AtomicLong和AtomicBoolean,可以用来解决这个问题。
小结
我尽力用比较简单的文字来描述java多线程和并发的问题。希望对大家有所帮助。
猜你喜欢
- 2024-09-14 Java 并发基础之并发编程通识,掌握高效编程的关键
- 2024-09-14 死磕「并发编程」100天,全靠阿里大牛的这份最全「高并发套餐」
- 2024-09-14 Java高并发编程详解:深入理解并发核心库,文字可复制,高清PDF
- 2024-09-14 Java并发不止于编程更是艺术,阿里技术专家编写257页PDF,给我啃
- 2024-09-14 Java并发编程应该掌握的并发工具类,快来看看你掌握了哪些?
- 2024-09-14 spring源码解析、并发编程实战实践等深度进阶电子文档分享
- 2024-09-14 干货推荐|Java并发编程核心概念一览,面试必备
- 2024-09-14 高并发编程系列:全面剖析Java并发编程之AQS的核心实现
- 2024-09-14 JAVA并发编程(Java并发编程实战(中文版)pdf)
- 2024-09-14 "深度解析Java并发编程:线程实战篇,一文掌握多线程高效
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)