前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >操作的原子性与线程安全

操作的原子性与线程安全

作者头像
FunTester
发布2019-07-27 18:43:47
1.2K0
发布2019-07-27 18:43:47
举报
文章被收录于专栏:FunTesterFunTester

本案例来源于java zone社区,由于源代码里面存在一些自己开发的注解,我暂时没找到相关的文档,所以我做了一些修改。用的都是java SDK的API。

关于概念:

  • 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
  • 线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
  • 线程不安全:就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

进入正题,如果可以从多个线程调用所有方法而没有外部同步,则类是线程安全的。为了实现这一点,线程安全方法必须是原子的,例如,其他线程只能看到方法之前或之后调用之间的状态。以下示例说明了为什么线程安全方法必须是原子的:

代码语言:javascript
复制
public class TR extends FanLibrary {
    private volatile int i = 0;
    public void ss() {        sleep(100);//为了更容易出现效果        i++;    }
    @Before    public void be() {        output("before");    }
    @Test    public void sdfa() throws InterruptedException {        Thread first = new Thread(() -> {            ss();        });        Thread second = new Thread(() -> {            ss();        });        first.start();        second.start();        first.join();        second.join();        output(i);    }
    @After    public void ds() {        output("after");    }}

控制台输出,以下内容可能会出现,代码中sleep(100)的原因:

代码语言:javascript
复制
INFO-> beforeINFO-> 1INFO-> after

其中“i++;”相当于“i = i + 1;”包含了“i + 1”和“i =”两个过程,不属于原子操作,所以在多线程访问该方法的时候是不安全的。

当两个线程同时获取到i = 0的值时,如果此时都没有执行到“i =”这个步骤的时候,那么两个线程等号右边都是1,然后前后执行“i = 1” 这个操作,相当于i最终被两次赋值为1,所以最终“i = 1”

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档