什么是线程安全?

了解线程安全 首先了解什么叫临界区

临界区 竞争条件

对于5000次的i++ i–结果不是0原因是因为在jvm底层的字节码流程是先获得这个i 然后再增加 再写回 **刚增加完还没有写回就已经被另一个线程取走了
** i++背后有多步 某一步骤就会被另一个线程抢夺 加上sychornized确保当前这个i++的临界区完成了 在别的线程进
代码块被称为临界区 :对其中的共享资源有读写操作
i++ jvm指令读取i 将i增加
在这里插入图片描述

sychronized

枷锁之后流程:获得对象锁 其他对象请求获得对象锁 但是被阻塞 当前对象释放锁之后还会唤醒阻塞队列中的进程
sychronized用对象锁保证了临界区代码的原子性
原子性是临界区会被全部执行完
对象锁就必须保证所有的临界区都被同一个对象上锁
不能不同对象 不能有不上锁的不上锁就是不会请求对象锁 那就不会被阻塞

这个线程不安全指的就是:多线程的最大问题在于对同一资源操作 因为你线程上下文切换又不会影响什么 你还会再恢复回来 但是如果是统一资源就真的是你切换还回来数已经改了
抢夺cpu的时候 在抢夺的过程很有可能当前的线程还没有完成操作因为操作有很多步骤比如 list.add(1)最后一步还没有加1 就被其他线程抢夺了 list.remove()那删除空的就报错了

共同资源才会有线程之间的联系 如果你都不是共同资源比如下面这个局部变量都是在自己的线程里 互不打扰 那就没有联系啊 就不会有什么资源的

静态变量和成员变量

private不被共享是线程安全的
JAVA有继承,在父类保证了线程安全,在子类你引用了父类,如果程序员没有去维护子类,那子类就不安全了,protected,同包引用
共享的的话成员变量就多个对象调用这一个成员读写操作就会线程不安全

局部变量没有暴露时是线程安全的

  • 因为每一个线程都有自己的栈 每一栈都是私有的 栈当中有栈帧
    栈帧当中存储局部变量 虽然是对同一块代码执行但是不同的线程开辟自己的栈帧有着自己初始化的局部变量不是共同资源所以是线程安全的
  • 局部变量=真正的局部声明的变量+形参+返回值
    返回值或者形参 如果暴露给外部 不止是在当前的线程间流传
    有别的线程调用返回值操作或者传形参那就产生不安全。 别的线程覆盖当前的某个线程也会不安全。没有其他的机会能够修改我当前的线程保证我当前的线程还是不被共享的 比如重写重载
  • 线程安全:1个线程安全 / 多个线程不同资源 安全/ 多个线程相同资源又不设置临界区的原子性那就不安全了

在同一个线程下几个函数互相调用 没问题 都是指向的同一个对象
局部变量多个线程也没问题因为每一个线程守护自己的局部变量值
最怕多个线程种有人获得了别的线程的局部变量 多个线程又对统一资源操作了

线程安全:多个线程调用同一实例的某个方法,方法是原子的,是线程安全的

线程安全例子理解: 线程安全就是指对于同一资源(方法,变量)有多个线程操作 那我们为了不让指令之间交错产生错误 就使临界区具有原子性
应用场景:servlet 多个线程同时访问srvlet时候要对servlet种调用的变量 方法线程安全控制

线程安全的类

不可变类(String +封装类) 因为他们只可以读
hashtable vector StringBuffer Random
他们的每个方法都是原子性的
如果多个线程执行这些实例的同一个方法都不会有问题 因为他们的方法都有原子性
方法组合在一起未必是线程安全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值