volatile与synchronized的作用与区别
一、volatile的用法与作用
用来修饰变量例如:Thread类里面的表示名字的字符数组
其作用是保证数据的可见性和有序性,但它并不能保证数据的原子性
顺便提一下。什么叫原子性?原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
因为volatile不能保证原子性,所以就引出了下面一个关键字 synchronized
二、synchronized的用法与作用
它用于修饰代码块和方法,可以弥补volatile关键字的不足,即它能保证对数据操作的原子性,在多个线程对数据进行操作时,保证线程的安全
synchronized提供了两种特性:互斥性和可见性
互斥性:如果将锁加在某个变量上,则每次只有一个线程能够使用该共享数据,直到该线程使用完才会将该共享数据释放,供其它线程使用。
可见性:线程在得到锁时读入副本,释放时写回内存。
下面是卖票的案例:
package com.dxx.synchroniz;
public class Task implements Runnable {
boolean flag = false;
int num = 5000;
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (flag) {
synchronized ("a") {
if (num > 0) {
System.out.println(Thread.currentThread() + "--同步代码块卖票--" + num--);
}
}
} else {
sell();
}
}
}
// 同步方法
public synchronized void sell() {
if (num > 0) {
System.out.println(Thread.currentThread() + "--同步方法中卖票--" + num--);
}
}
}
控制台显示:
总结
综上所述,volatile与synchronized与区别如下:
1.修饰对象不同,volatile用于修饰变量,synchronized用与对语句和方法加锁;
2.各自作用不同,volatile保证数据的可见性和有序性,但它并不能保证数据的原子性,synchronized可以保证原子性;
3.volatile不会造成线程堵塞,而synchronized会造成线程堵塞;