java – 同步 – 与edegs编译器在两个方向重新排序障碍?
我有一个关于
Java内存模型的问题.给出以下示例:
action 1 action 2 synchronized(monitorObject) { //acquire action 3 } //release action 4 获取和释放可以是任何与边缘同步的(锁定,解锁,启动线程,连接线程,检测线程中断,易失性写入,易失性读取等) 是否保证在收购之前无法移动动作3,在发布后不能移动? 并且保证行为2在获得后不能移动(既不在释放之前也不在释放之后),并且动作4在释放之前不能移动(在获取之前和之后)? 同步 – 与边缘“双向屏障”编译器的重新排序动作? 编辑1 还是双向重新排序障碍,甚至不需要防止这种情况,因为锁获取不能被推入其他,因为这会改变同步顺序? 编辑2 编辑3 x和y是共享变量,syncA和syncB可以由任何其他线程获取.但是使用以下代码,没有可能的死锁. /* 1 */ synchronized(syncA) { /* 2 */ x = 1; /* 3 */ } /* 4 */ y = 0; /* 5 */ synchronized(syncB) { /* 6 */ y = 1; /* 7 */ } 但是,如果将syncA的获取重新排序到syncB块中,则可能会导致死锁: y = 0; synchronized(syncB) { y = 1; synchronized(syncA) { x = 1; } } 我认为这不是一个合法的编译器转换,因为它会改变同步顺序.我有这个假设吗? Java内存模型(JMM)的哪一部分允许/禁止这一点? 解决方法
感谢
assylias链接到
this question,其中包含从
JSR-133 Cookbook的这个图像的答案:
根据这个图像,编辑器从EDIT 3转换是非法的,因为它重新排列两个MonitorEnters. 此外,该表还显示了哪些同步边缘是什么样的“重新排序障碍”,为其他操作. 感谢您的帮助 :) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |