java基础多线程(4)—线程可见性volatile 线程封闭threadlocal CAS操作

一。线程的可见性volatile(不是太常用,因为他只能解决线程可见和阻止指令排序,并不能解决多线程的并发问题)

volatile:(1)保证变量的修改让所有线程可见

(2)阻止指令排序

 

这个程序有3个结果,0,42,没有进入循环直接结束

  • 42:正常跑

  • 0:yeild以后直接继续跑run的线程了

  • 没有进入循环直接结束:这个就比肩奇怪了,除非这句话先运行了,否则是不会这样的啊。

   事实上就是这句话线运行了,可是为什么会这样呢,cpu实际有一个指令排序的问题,几个指令在一起在逻辑允许的情况下不是按顺序运行的,比如运行慢的语句就后执行。

volatile关键字就可以解决这个问题,解决程序的可见性,加上了volatile可以确定其位置的语句在此处执行(意思就是它上面的一堆语句还是不安书序执行,但是一定是上面群执行完了再执行他,然后再执行下边的语句)

 

下边这个例子是从另外一个层面讲的,

上下两个线程都是无限循环的,正常情况下,2线程修改了bchange后一线程也就停止了,但是实际运行后直接卡死了,因为bchange一直没改变,

为什么呢,因为cpu有内存和缓存,运行时是放到缓存里里运行的,而第二个线程修改的值是直接放进内存的,一线程的缓存里一直有数据,所以他根本不去看内存,只看缓存,即使2线程改变了值,一线程也是看不到的。

  这时就可以用volatile,让他必须从内存里读数据。

 

 

 

二,CAS操作

compare and  set      先比较后修改 

  一般的并发问题都还cas操作,一线程比较后修改了值,这时二线程也来比较修改值,但它可能修改的是之前的值,所以才需要锁,或者原子性

 

 

三,线程封闭threadlocal

首先介绍一种封闭——栈封闭,比如方法内部的声明修改都是不会溢出的,因为有方法栈啊,方法用完了就释放了,别人也用不了(细致了解的自己百度)

threadlocal线程绑定,

当你想操作一组数据,又不受其他线程的干扰,就用它,他会给每一个线程绑定一个自己的副本,自己用自己的,不会打架

 

使用:把threadLocal对象放进threadlocal.set(),这样就制作了一个副本,再用get()拿出来,进行后续的操作。

注意:我爱主函数里只new了一个threadLocal,然后有两个线程同时使用它(改了数字并println),如果按平时的话,现成话打架的,但是把threadLocal对象放进threadlocal,set()之后就不会打架了,实际就是生成了不同的副本,各操作各的,互不干扰。

//这就是一个普通的bean来演示

public class TheadText {

    private int num;



    public int getNum() {

        return num;

    }



    public void setNum(int num) {

        this.num = num;

    }

}

public class test {

   public static void main(String[] args){

       ThreadLocal<TheadText> threadLocal=new ThreadLocal();    //new一个ThreadLocal  

       TheadText theadText=new TheadText();

  

//把threadLocal对象放进threadlocal.set(),这样就制作了一个副本,再用get()拿出来,进行后续的操作。

      new Thread(){

          @Override

         public void run(){

              for (;;){

                  threadLocal.set(theadText);

                  TheadText  theadText1=threadLocal.get();

                  theadText1.setNum(111);

                  System.out.println(Thread.currentThread().getName()+":"+theadText1.getNum());

                  Thread.yield();

              }

         }

      }.start();



       new Thread(){

           @Override

           public void run(){

               for (;;){

                   threadLocal.set(theadText);

                   TheadText  theadText2=threadLocal.get();

                   theadText2.setNum(222);

                   System.out.println(Thread.currentThread().getName()+":"+theadText2.getNum());

                   Thread.yield();

               }

           }

       }.start();

   }

}

结果;并没有打架

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值