java多线程编程关键字volatile,ThreadLocal和synchronized
来源:互联网 发布:合肥软件开发 编辑:程序博客网 时间:2024/05/18 03:43
1.volatile
volatile主要是用来在多线程中同步变量。
在一般情况下,为了提升性能,每个线程在运行时都会将主内存中的变量保存一份在自己的内存中作为变量副本,但是这样就很容易出现多个线程中保存的副本变量不一致,或与主内存的中的变量值不一致的情况。
而当一个变量被volatile修饰后,该变量就不能被缓存到线程的内存中,它会告诉编译器不要进行任何移出读取和写入操作的优化,换句话说就是不允许有不同于“主”内存区域的变量拷贝,所以当该变量有变化时,所有调用该变量的线程都会获得相同的值,这就确保了该变量在应用中的可视性(当一个任务做出了修改在应用中必须是可视的),同时性能也相应的降低了(还是比synchronized高)。
但需要注意volatile只能确保操作的是同一块内存,并不能保证操作的原子性。所以volatile一般用于声明简单类型变量,使得这些变量具有原子性,即一些简单的赋值与返回操作将被确保不中断。但是当该变量的值由自身的上一个决定时,volatile的作用就将失效,这是由volatile关键字的性质所决定的。
所以在volatile时一定要谨慎,千万不要以为用volatile修饰后该变量的所有操作都是原子操作,不再需要synchronized关键字了。
2.ThreadLocal
首先ThreadLocal和本地线程没有一毛钱关系,更不是一个特殊的Thread,它只是一个线程的局部变量(其实就是一个Map),ThreadLocal会为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。这样做其实就是以空间换时间的方式(与synchronized相反),以耗费内存为代价,单大大减少了线程同步(如synchronized)所带来性能消耗以及减少了线程并发控制的复杂度。
个人觉得比较典型的例子就是在Android关于Looper的源码中对ThreadLocal的使用,同时也包含了ThreadLocal的基本用法,具体代码如下:
public class Looper { private static final String TAG = "Looper";// sThreadLocal.get() will return null unless you've called prepare(). private static final ThreadLocal sThreadLocal = new ThreadLocal(); ...... private static Looper mMainLooper = null; ...... public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); } ...... public static final void prepareMainLooper() { prepare(); setMainLooper(myLooper()); ...... } private synchronized static void setMainLooper(Looper looper) { mMainLooper = looper; } public synchronized static final Looper getMainLooper() { return mMainLooper; } ...... public static final Looper myLooper() { return (Looper)sThreadLocal.get(); } ...... }
但需要注意的是,虽然ThreadLocal和Synchonized都用于解决多线程并发访问,ThreadLocal与synchronized还是有本质的区别。synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。即Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。所以ThreadLocal并不能代替synchronized,Synchronized的功能范围更广(同步机制)。
3.synchronized
synchronized关键字是Java利用锁的机制自动实现的,一般有同步方法和同步代码块两种使用方式。Java中所有的对象都自动含有单一的锁(也称为监视器),当在对象上调用其任意的synchronized方法时,此对象被加锁(一个任务可以多次获得对象的锁,计数会递增),同时在线程从该方法返回之前,该对象内其他所有要调用类中被标记为synchronized的方法的线程都会被阻塞。当然针对每个类也有一个锁(作为类的Class对象的一部分),所以你懂的^.^。
最后需要注意的是synchronized是同步机制中最安全的一种方式,其他的任何方式都是有风险的,当然付出的代价也是最大的。
参考博文:http://www.jb51.net/article/62630.htm
- java多线程编程关键字volatile,ThreadLocal和synchronized
- Java 多线程编程之synchronized 和 volatile关键字
- Java——多线程总结、ThreadLocal/Volatile/synchronized/Atomic关键字
- java多线程之synchronized和volatile关键字
- java关键字volatile和synchronized在多线程中的应用
- java 关键字synchronized和volatile
- ThreadLocal、volatile、synchronized、Atomic关键字
- 并发编程之ThreadLocal、Volatile、synchronized、Atomic关键字扫盲
- 并发编程之ThreadLocal、Volatile、synchronized、Atomic关键字扫盲
- 并发编程之ThreadLocal、Volatile、synchronized、Atomic关键字扫盲
- 并发编程之ThreadLocal、Volatile、synchronized、Atomic关键字扫盲
- 并发编程之ThreadLocal、Volatile、synchronized、Atomic关键字扫盲
- JAVA多线程系列--关键字(volatile,synchronized)
- Java多线程volatile和synchronized
- Java多线程中的synchronized、volatile和无锁编程
- Java多线程编程-volatile关键字
- JAVA多线程编程---volatile与synchronized
- java线程5 volatile和synchronized关键字 .
- php连接sqlserver的方法
- Maven父子项目打包子项目出现Failed to collect dependencies问题
- [C++]vector 的 push_back实现原理
- 【数据存储】——JSON与XML的对比
- 模板:Edmonds_Karp 算法
- java多线程编程关键字volatile,ThreadLocal和synchronized
- 非阻塞connect()
- Java POI 导出EXCEL经典实现 Java导出Excel弹出下载框
- 【图像处理】颜色距离
- 使用内部类来实现Java的”多继承“
- 四大组件之Service 生命周期(3)
- jsp用到的标签
- 技术记录---Handle收不到消息的问题分析
- poj 3414 pots