002--volatile 关键字-内存可见性

2018-05-04  本文已影响27人  糖纸疯了

话题一:多线程的3种创建方式

Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。Java可以用三种方式来创建线程,如下所示:
1)继承Thread类创建线程
2)实现Runnable接口创建线程
3)使用Callable和Future创建线程


话题二:wait和notify的理解与使用

因为他们是用来操纵锁的,而每个对象都有锁,锁是每个对象的基础,既然锁是基础的,那么操纵锁的方法当然也是最基础了.


话题三:同样是线程休眠:wait(),sleep(),suspend()有什么区别呢?


话题四:wait()暂时放弃对象锁后,如何将对象锁收回来?


话题五:线程的可用方法展示

查看Thread线程的方法

话题六:synchronized和volatile?

1.volatile问题引出

// 老师演示的时候,有一个问题,虽然子线程falg=true,但是main线程打印依然是false!但是在我的JDK上没有重现这一个现象
public class TestVolatile {
    public static void main(String[] args) throws Exception {
        // 1.创建一个线程
        MyThreadA myThreadA = new MyThreadA();
        new Thread(myThreadA).start();
        new Thread(myThreadA).start();
        
        // 2.mian主线程
        while(true){
            if (myThreadA.flag) {
                System.out.println("-------------主线程flag:"+myThreadA.flag);
                Thread.sleep(1000);
            }else{
                System.out.println("*************主线程flag:"+myThreadA.flag);
                Thread.sleep(1000);
            }
        }
    }
}
class MyThreadA implements Runnable{
    public boolean flag = Boolean.FALSE;
    
    @Override
    public void run() {
        try {
            System.out.println("-----------自定义线程执行休眠1s");
            Thread.sleep(200);
            flag = Boolean.TRUE;
            System.out.println("-----------休眠结束flag:"+flag);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2.synchronized(object){}代表什么含义?
- 只能由一个线程同时使用object
- 多线程时,先判断锁,有锁就要将后续线程阻塞挂起,直到下一次CPU重新给他进行任务分配
- 加锁的这种效率是最低的!但是又需要刷新数据(内存可见性的问题),怎么办?--volatile
- volatile可以保证多个线程在访问相同数据时候,数据是实时可见的(实时将缓存数据刷新到主存中)!


3.synchronized和volatile比较
- volatile对比于synchronized,是一种轻量级的同步策略!
- volatile不具备"互斥性",不能保证只有一个线程使用共享数据
- volatile不能保证变量的原子性


4.什么是原子性?

  i++ 的原子性问题:i++ 的操作实际上分为三个步骤“读-改-写”
  int i = 10;
  i = i++; //10

  int temp = i;
  i = i + 1;
  i = temp;
- 本身来说,i++不能将过程进行拆解,但是volatile不能保证原子性,如果在多线程下就会被拆开,数据的执行结果就会出错!
上一篇下一篇

猜你喜欢

热点阅读