多线程共享内存时存在的问题

  1. 竞态条件
    当多个线程处理同一块内存区域时,有于对共享内存的操作不是原子操作,会造成语句的执行得不到期望的结果
    eg:
public class CounterThread extends Thread {
    static int count = 0;
    static int num = 1000;
    @Override
    public void run() {
        for(int i = 0; i < num; i++){
            count++;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread[] threads = new CounterThread[num];
        for(int i = 0; i < num; i++){
            threads[i] = new CounterThread();
            threads[i].start();
        }
        for(int i = 0; i < num; i++){
            threads[i].join();
        }
        System.out.println(count);
    }
}

count做为共享变量,所用线程并发执行时操作同一块内存
count++并非原子操作,当执行此语句时分解为三个原子操作
取出count值
为count值加一
为count变量赋值
假设count值为100,有两个线程近乎同时的取出count值,为其加一,然后将其赋值给count变量,此时我们得到的count变量中的值为101而非预期中的102
(2)内存可见性
当cpu操作某个数据后并不一定直接写会内存,而是保存到寄存器或cpu缓存中,此时即使共享变量已改变,其他线程也看不到,因为一旦执行其他线程,cpu则需切换上下文,此时当前线程只能从内存中得到其他线程操作后的数据状态。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 以上代码会重复运行 , 不会停止。 JMM(java内存模型) 若想学习好多线程, 那么必须了解一下JMM Jav...
    尼尔君阅读 1,767评论 0 2
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,161评论 1 32
  • Java内存区域 Java虚拟机在运行程序时会把其自动管理的内存划分为以上几个区域,每个区域都有的用途以及创建销毁...
    架构师springboot阅读 1,818评论 0 5
  • Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态,线程之间通过写-读内存中的公共...
    阿斯蒂芬2阅读 507评论 0 1
  • 线程池ThreadPoolExecutor corepoolsize:核心池的大小,默认情况下,在创建了线程池之后...
    irckwk1阅读 778评论 0 0