多线程(3)线程安全以及解决方案

1.线程安全问题

1.线程安全案例:

我们在使用多线程的时候常常会遇到线程安全的问题

如图:

public class Demo11 {
    static int count=0;
    public static void main(String[] args) throws InterruptedException {
        Thread thread1=new Thread(()->{
            for (int i = 0; i <50000 ; i++) {
                count++;

            }
        });
        Thread thread2=new Thread(()->{
            for (int i = 0; i <50000 ; i++) {
                count++;
            }

        });
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println(count);
    }
}

在这里按理来说我们两个线程同时对count进行相加答案应该是100000,但是实际上答案却是比100000小。这是因为两个线程为了同时拿到count而有冲突的原因。

2. 线程安全的概念

概念:想给出一个线程安全的确切定义是复杂的,但我们可以这样认为:

如果多线程环境下代码运行结果是符合我们预期的,即在单线程环境应该的结果,则说这个线程是线程安全的。

3.线程不安全的原因

1.线程是抢占式执行的:线程通常会优先抢占系统资源。

2.系统同时对同一个进行修改和操作:上面就是同时对count进行操作。

3.原子性:对数据的修改不是原子性的。

4.内存可见性和指令重排序:

2:线程安全的解决方案

首先我们要了解count在自增的过程:

  1. 1.load把数据从内村读到cpu寄存器中
  2. 2.add将数据+1
  3. 3.save将寄存器中的值保存到内存中

由于俩个线程的不同load,add,save的顺序不同就很有可能会出现问题。

1.synchronized关键字

上述操作都是非原子操作,也就是操作不是一个整体,打包成一个操作,也就是非原子操作打包成原子操作。此时我们就要用到synchronized()。也就是加锁。

synchronized 的互斥特性:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值