synchronized属于对象锁可以保证多线程的安全,但是会造成阻塞比较严重。即使对synchronized进行优化,也会留有一定的阻塞,对计算机的性能不太友好。
volatile关键字相当于内存和cpu之间的放哨员,如果有synchronized修饰的变量a,在多线程同时访问变量a并进行修改成b时,如果有某个线程已经把a改为b了,就会返回给内存,并提醒其他核的cpu:“变量a已改,无需再改”。
volatile实例
package practice;
//volatile关键字作用(修饰类中属性)
//1.保证线程的可见性()
//2.禁止指令重排序
//3.但不能保证其原子性
class Singleton06{
public Singleton06() {
System.out.println("instance");
}
//volatile不能修饰方法一般都是修饰变量属性
private static volatile Singleton06 instance ;
public static Singleton06 getInstance() {
if (instance==null) {
instance = new Singleton06();
}
return instance;
}
}
public class TestObjectInstance_practice {
public static void main(String[] args) {
//记录当前时间
long a=System.currentTimeMillis();
//执行多线程访问
doTestManyThread();
//输出执行时间
System.out.println("\r<br>执行耗时 : "+
(System.currentTimeMillis()-a)/1000f+" 秒 ");
}
private static void doTestManyThread() {
class Task implements Runnable {
@Override
public void run() {
Singleton06.getInstance();
}
}
//调用一千个线程访问获取instance变量
for (int i = 0; i <1000; i++) {
new Thread(new Task()).start();
}
}
}
运行结果:
synchronized例子:
package practices;
//synchronized 保证代码的原子性(不能同时有多个线程在这代码)
//synchronized 要让多个线程在这个代码块上顺序执行
//此设计虽然保证了线程安全,性能却大大减低
//重构方法的设计,优化synchronized(既要保证线程的安全,又减少阻塞)但是在高并发中阻塞依然明显
class Singleton03{
public Singleton03() {
System.out.println("创建对象instance");
}
private static Singleton03 instance ;
public static Singleton03 getInstance() {
if (instance==null) {
synchronized (Singleton03.class) {
if(instance==null) {
instance = new Singleton03();
}
}
}
return instance;
}
public class TestObjectInstance_practice {
public static void main(String[] args) {
//记录当前时间
long a=System.currentTimeMillis();
//执行多线程访问
doTestManyThread();
//输出执行时间
System.out.println("\r<br>执行耗时 : "+
(System.currentTimeMillis()-a)/1000f+" 秒 ");
}
private static void doTestManyThread() {
class Task implements Runnable {
@Override
public void run() {
Singleton03.getInstance();
}
}
for (int i = 0; i <1000; i++) {
new Thread(new Task()).start();
}
}
}
运行结果:
从两个运行结果可以看出,
volatile修饰后,创建了三个对象,所以没有确保原子性,但是运行时间却比synchronized少很多。
synchronized的运行结果,只创建一个instance对象,可以确保原子性,但是运行时间却比volatile长,造成一定的阻塞。