当前位置: 首页 > news >正文

江西建设厅官方网站关键词优化公司排名

江西建设厅官方网站,关键词优化公司排名,做药品网站有哪些,合肥网络推广软件最近在阅读FutureTask的源码是发现了一个问题那就是源码中封装结果的字段并没有使用volatile修饰&#xff0c;源码如下&#xff1a;public class FutureTask<V> implements RunnableFuture<V> {/*** 状态变化路径* Possible state transitions:* NEW -> COMPLET…

最近在阅读FutureTask的源码是发现了一个问题那就是源码中封装结果的字段并没有使用volatile修饰,源码如下:

public class FutureTask<V> implements RunnableFuture<V> {/*** 状态变化路径* Possible state transitions:* NEW -> COMPLETING -> NORMAL* NEW -> COMPLETING -> EXCEPTIONAL* NEW -> CANCELLED* NEW -> INTERRUPTING -> INTERRUPTED*/private static final int NEW          = 0;private static final int COMPLETING   = 1;// 完成中private static final int NORMAL       = 2;// 正常结束// 异常private static final int EXCEPTIONAL  = 3;// 取消任务private static final int CANCELLED    = 4;// 中断任务private static final int INTERRUPTING = 5;// 被中断的private static final int INTERRUPTED  = 6;// 任务执行状态private volatile int state;// 待执行的任务private Callable<V> callable;// 封装的结果,或则执行的异常private Object outcome; // non-volatile, protected by state reads/writes// 执行当前任务的线程 通过CAS来设置private volatile Thread runner;// 所有等待获取执行结果的线程,被封装为一个链表数据结构private volatile WaitNode waiters;
}

我们看到state字段是volatile修改的,但是outcome字段并没有volatile修饰。

继续看下这两个字段如何设置值的:

// 1. 正常结束设置结果
protected void set(V v) {// 设置状态为完成中if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {// 设置结果outcome = v;// 设置状态为正常结束UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state// 后续事宜:唤醒等待的线程,调用done()方法finishCompletion();}
}// 不带超时时间
public V get() throws InterruptedException, ExecutionException {int s = state;// 状态小于等于完成中...(NEW,COMPLETING)if (s <= COMPLETING)// 等待s = awaitDone(false, 0L);// return report(s);
}

咋一看,好像看不出什么名堂,这里能清楚得出结论的是state字段在get()方法中是可见的。

但是,outcome字段并没有volatile修饰,不能直接得出outcome字段在get()方法中也是可见的这样的结论。

happen-before

要搞清楚这个问题,我们首先来复习下volatile关键字的作用:

Happens-Before原则:前面一个操作的结果对后续操作是可见的。

Happens-Before原则约束了编译器的优化行为,虽允许编译器优化,但是要求编译器优化后一定遵守Happens-Before原则。即使编译器进行指令重排序的优化,如果结果和重排序前一致,也是允许的。

java1.5之后,通过happen-before原则增强了volatile关键词。volatile关键词是轻量的实现线程安全的方法,保证了volatile变量的有序性和可见性。

可见性保证

当写 volatile 变量时,JMM 会立即把该线程对应的本地内存中的共享变量值刷新到主内存。

当读 volatile 变量时,JMM 会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。

volatile 保证内存可见性,其实是用到了 CPU 保证缓存一致性的 MESI 协议。当某线程对 volatile 变量的修改会立即回写到主存中,并且导致其他线程的缓存失效,强制其他线程再使用变量时,需要从主存中读取。

编译器有以下规则:

  1. 在每个volatile写操作的前面插入一个StoreStore屏障

  1. 在每个volatile写操作的后面插入一个StoreLoad屏障

  1. 在每个volatile读操作的后面插入一个LoadLoad屏障

  1. 在每个volatile读操作的后面插入一个LoadStore屏障

接下来我们来分析案例,对于如下代码:

private volatile int state;
private Object outcome;public void set(Object v){if(state == NEW){     // 1outcome = v;            // 2state = DONE;            // 3}
}public void get(){if(state == DONE){            // 4return outcome;            // 5}return null;
}

根据volatile的happen-before原则,2对3是可见的,同时4对5是可见的,并且3对4是可见的,那么根据传递性: 2 < 3 < 4 < 5,我们不难得出,2 < 5成立,即2对5可见

这里还有个问题就是多线程调用set()方法情况下存在竞争,我们继续改进set()方法。

private volatile int state;
private Object outcome;public void set(Object v){if(compareAndSet(state,NEW,DONE)){     // 1outcome = v;                       // 2}
}
public void get(){if(state == DONE){            // 4return outcome;           // 5}return null;
}

这里解决了修改state字段的原子性,但是并不能保证刚才的2对5可见了,因为这里满足1对2可见,4对5可见,同时1对4可见,这里我们没法办推到出2对5可见

继续修改,为了保证2对5的可见性,我们还是得保留3这一行代码。

那么我们完全可以增加一个中间临时变量TMP,代码就改成这样:

private volatile int state;
private Object outcome;public void set(Object v){if(compareAndSet(state,NEW,TMP)){   // 1outcome = v;                    // 2state = DONE;                   // 3}
}public void get(){if(state == DONE){            // 4return outcome;            // 5}return null;
}

这样我们既保证了设置state字段的原子性,同时保证了outcome字段对get()方法的可见性。

这完全就是FutureTask中outcome的实现逻辑,所以我们已经正确分析了outcome为什么可以不加volatile关键字,也能保证可见性的原因。

http://www.hkea.cn/news/105181/

相关文章:

  • 我是做环保类产品注册哪些浏览量大的网站推销自己的产品比较好呢西安网站seo优化公司
  • 网页传奇游戏排行昆明网络推广优化
  • 商城模板网站模板网站软文是什么
  • 校园网站推广方案怎么做网站排名推广工具
  • 深圳罗湖企业网站建设报价网络媒体发稿平台
  • 用别人公司域名做网站线下推广的渠道和方法
  • php mysql的网站开发外贸推广平台
  • 济南网站建设认可搜点网络能百度指数有三个功能模块
  • 网上商城网站建设意义在线代理浏览网页
  • 网站图片切换代码百度下载并安装最新版
  • 微信公众平台号申请注册入口杭州seo公司
  • 本周实时热点新闻事件seo文章代写一篇多少钱
  • 旺店通app手机企业版下载网站seo如何优化
  • 宝山区建设用地事务所网站网络公司有哪些
  • 用sql做简单的博客网站大连谷歌seo
  • 新手怎么学做网站就业培训机构有哪些
  • magento网站建设搭建网站步骤
  • 营销网站如何实现差异化南京seo公司
  • 服务器托管是啥搜索引擎优化排名培训
  • 山西手机网站建设网址大全123
  • b2c平台有哪些平台网址新区seo整站优化公司
  • WordPress突然全站404网站如何添加友情链接
  • 复制别人网站做第一站seo短视频网页入口引流下载
  • 基层建设论文收录在哪个网站百度统计api
  • 购买主机可以做网站吗楚雄今日头条新闻
  • 深圳专业网站建设公司哪家好宁波网络营销公司
  • ps做电商网站流程图百度图片识别搜索引擎
  • 做电影网站程序好用武汉网站建设推广公司
  • 如何做b2c网站下列关于友情链接说法正确的是
  • 网站开发中网页上传seo在线网站推广