网站首页 > java教程 正文
前言
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多线程和并发的问题。希望对大家有所帮助。
- 上一篇: Java并发编程(java并发编程实战)
- 下一篇: 干货:Java并发编程必懂知识点解析
猜你喜欢
- 2024-10-13 GitHub热点推荐!85W字并发编程图册(全彩版),竟是出自阿里
- 2024-10-13 「不得不看」Java并发编程一(java并发编程之美)
- 2024-10-13 深入理解java并发编程、并发编程相关概念基础篇
- 2024-10-13 Java 高并发编程详解:多线程与架构设计首稿写作完成
- 2024-10-13 Java面试专题——并发编程(juc并发编程面试题)
- 2024-10-13 Java编程——如何实现高效的并发控制
- 2024-10-13 Java线程与并发编程实践:深入理解volatile和final变量
- 2024-10-13 简单理解JAVA并发编程及高并发(java并发编程实战和并发编程的艺术)
- 2024-10-13 高并发编程系列:全面剖析Java并发编程之AQS的核心实现
- 2024-10-13 Java 多线程并发编程(关于java多线程并发控制机制)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)