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

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

(2)阻止指令排序

 

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

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

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

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

  • 42:正常跑

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

  • 没有进入循环直接结束:这个就比肩奇怪了,除非java基础多线程(4)—线程可见性volatile 线程封闭threadlocal CAS操作这句话先运行了,否则是不会这样的啊。

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

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

 

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

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

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

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

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

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

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

 

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

 

 

二,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();

   }

}

结果;并没有打架

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

相关文章:

  • 2022-12-23
  • 2021-11-16
  • 2022-01-29
  • 2021-04-03
  • 2021-07-13
  • 2021-05-25
  • 2022-12-23
  • 2021-10-24
猜你喜欢
  • 2021-04-30
  • 2022-12-23
  • 2021-09-05
  • 2021-12-29
  • 2021-10-01
  • 2021-11-24
相关资源
相似解决方案