• Java多线程分析 (二)---- 高并发内存模型和线程安全


    1.原子性:

    原子性指一个操作不可中断的CPU操作是原子性:i++不是原子性:分为读取---i++--写入的操作,在类Java.concurrent.atomic类中,这样将操作分解成原子性的操作

    2.有序性

    当指令分解多个小小步骤:分解成流水线型操作:在每个时钟周期,从编译原理上理解:当执行到MEM过程放在缓存中,指令重排过程进行优化代码

    3.可见性问题:没有后面进行加锁等操作,直接运行,有可能会发生指令重排(计算机自己出现一些不同结果)

    一个线程修改一个共享资源,其他线程是否能够立马得知

    4.Happen-Before规则:

    5.CAS操作(无锁操作):采用AtomicstampedReferencej解决一个经典的ABA问题

     1 package AtomicTest;
     2 
     3 import java.util.concurrent.atomic.AtomicStampedReference;
     4 
     5 public class AtomicStampedReferenceDemo {
     6    static AtomicStampedReference<Integer> moneny=new AtomicStampedReference<Integer>(19,0);
     7     public static void main(String[] args) {
     8         // TODO Auto-generated method stub
     9             //三个充值程序在这里监控,一个消费程序
    10         for(int i=0;i<3;i++)//执行三个充值消费监控
    11         {    final int timestamp=moneny.getStamp();//第一个参数表示先有余额,第二个参数表示充值次数
    12             new Thread()
    13             {
    14                 //每一个进程有自己的run方法
    15                 public void run()
    16                 {
    17                     while (true)
    18                     {
    19                         Integer    m=moneny.getReference();
    20                         if(m<20)
    21                         {
    22                             if(moneny.compareAndSet(m,m+20,timestamp,timestamp+1))
    23                             {
    24                                 System.out.println("余额不足,自动充值20元,现有余额  "+moneny.getReference());
    25                                 break;
    26                             }
    27                             else
    28                             {
    29                                 System.out.println("以帮你充值一次,无法在送");
    30                                 break;
    31                             }
    32                             
    33                         }
    34                         else
    35                         {
    36                             break;
    37                         }
    38                     }
    39                 }
    40             }.start();;
    41         }
    42         //用户模式
    43         new Thread(){
    44             public void run(){
    45                  for(int i=0;i<100;i++)
    46                  {
    47                      while(true)
    48                      {
    49                          Integer m=moneny.getReference();
    50                          int timestamp=moneny.getStamp();
    51                          if(m>10)
    52                          {
    53                              System.out.println("钱大于10元"+m);
    54                              if(moneny.compareAndSet(m,m-10,timestamp,timestamp+1));
    55                              {
    56                                  System.out.println("消费大于10元 "+moneny.getReference());
    57                                     break;
    58                              }
    59                             
    60                          }
    61                          else
    62                          {//为啥*。getReference会在cas被修改
    63                              System.out.println("没有足够的余额");
    64                              break;
    65                          }
    66                      }
    67                  }
    68             }
    69         }.start();
    70     }
    71     
    72 }
  • 相关阅读:
    F. 数学上来先打表
    LibreOJ β Round #2
    noip飞扬的小鸟
    jxoi2017
    分块算法
    Chino的数列
    cf 613E
    cf 126D
    cf 542E
    cf 512D
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/5788247.html
Copyright © 2020-2023  润新知