第十四篇:图文讲述同步的另一个重要功能:内存可见性

加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另外一个重要的方面:内存可见性。我们不仅希望防止某个线程正在使用对象状态而另一个线程在同时修改该状态,而且还希望确保当一个线程修改了对象状态后,其他线程能够看到该变化。而线程的同步恰恰也能够实现这一点。

     内置锁可以用于确保某个线程以一种可预测的方式来查看另一个线程的执行结果。为了确保所有的线程都能看到共享变量的最新值,可以在所有执行读操作或写操作的线程上加上同一把锁。下图示例了同步的可见性保证。

     当线程A执行某个同步代码块时,线程B随后进入由同一个锁保护的同步代码块,这种情况下可以保证,当锁被释放前,A看到的所有变量值(锁释放前,A看到的变量包括y和x)在B获得同一个锁后同样可以由B看到。换句话说,当线程B执行由锁保护的同步代码块时,可以看到线程A之前在同一个锁保护的同步代码块中的所有操作结果。如果在线程A unlock M之后,线程B才进入lock M,那么线程B都可以看到线程A unlock M之前的操作,可以得到i=1,j=1。如果在线程B unlock M之后,线程A才进入lock M,那么线程B就不一定能看到线程A中的操作,因此j的值就不一定是1。

     现在考虑如下代码:

[java]  view plain  copy
  1. public class  MutableInteger  
  2. {  
  3.     private int value;  
  4.   
  5.     public int get(){  
  6.         return value;  
  7.     }  
  8.     public void set(int value){  
  9.         this.value = value;  
  10.     }  
  11. }  


     以上代码中,get和set方法都在没有同步的情况下访问value。如果value被多个线程共享,假如某个线程调用了set,那么另一个正在调用get的线程可能会看到更新后的value值,也可能看不到。

     通过对set和get方法进行同步,可以使MutableInteger成为一个线程安全的类,如下:

[java]  view plain  copy
  1. public class  SynchronizedInteger  
  2. {  
  3.     private int value;  
  4.   
  5.     public synchronized int get(){  
  6.         return value;  
  7.     }  
  8.     public synchronized void set(int value){  
  9.         this.value = value;  
  10.     }  
  11. }  


     对set和get方法进行了同步,加上了同一把对象锁,这样get方法可以看到set方法中value值的变化,从而每次通过get方法取得的value的值都是最新的value值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个以方格图文图标展示功能名称和功能图标的 layui 功能模块展示界面的示例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Layui 功能模块展示界面</title> <link rel="stylesheet" href="https://cdn.staticfile.org/layui/2.5.6/css/layui.css"> <style> .module { border: 1px solid #e6e6e6; padding: 20px; text-align: center; background-color: #f8f8f8; } .module .icon { font-size: 50px; margin-bottom: 20px; } .module .name { font-size: 20px; font-weight: bold; margin-bottom: 10px; } </style> </head> <body> <div class="layui-container"> <div class="layui-row"> <div class="layui-col-md4"> <div class="module"> <i class="layui-icon layui-icon-user icon"></i> <div class="name">用户管理</div> <div class="desc">管理用户信息和权限</div> </div> </div> <div class="layui-col-md4"> <div class="module"> <i class="layui-icon layui-icon-form icon"></i> <div class="name">表单管理</div> <div class="desc">管理表单和表单数据</div> </div> </div> <div class="layui-col-md4"> <div class="module"> <i class="layui-icon layui-icon-template-1 icon"></i> <div class="name">模板管理</div> <div class="desc">管理页面模板和样式</div> </div> </div> </div> </div> <script src="https://cdn.staticfile.org/layui/2.5.6/layui.js"></script> </body> </html> ``` 在这个示例代码中,我们使用了 layui 的栅格系统和自定义样式,将三个功能模块以方格图文图标的形式展示在同一行中。你可以通过修改 `.layui-col-md4` 类的数量和 `.module` 类的内容,来增加或减少功能模块的数量和展示内容。同时,你还可以使用不同的 layui 图标来代替示例代码中的图标,来更好地展示你的功能模块。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值