• Synchronized同步性与可见性


    Synchronized是具有同步性与可见性的,那么什么是同步性与可见性呢?

    (1)同步性:同步性就是一个事物要么一起成功,要么一起失败,可谓是有福同享有难同当,就像A有10000去银行转5000给身无分文的B,这个事物有两个操作,1.A扣去5000 即剩下10000-5000=5000;2.B增加0+5000=5000;一起成功的情况就是1和2都成功执行,一起失败的情况是,如果A扣除的时候机器刚好坏了,那么事物就应该回滚,不然A就只剩5000,B还是0;这里没写例子

    (2).可见性:就是一个线程的操作可以及时被其他线程更新到;要做到线程可见性必须满足两个条件,这里要谈到JMM(java memory model),1.线程的工作内存副本的共享变量要更新到主存,2.其他线程要及时读取主存的共享变量

    为了更好理解 我截了个图 

    以下代码例子 是为了说明可见性的 是没有增加Synchronized 关键字  所以运行结果会出现 

    result的值为0 或者 result的值为50

    大家应该会疑问为什么会出现50? 这是不是代表没有加Synchronized  也可以实现可见性 ,其实没有加Synchronized 并不代表就一定不会出现可见性,只是概率事件

    package cs.util;
    
    public class SynchronizedDemo {
    private boolean start=false;
    private int result=0;
    private int count=0;
    
    //读操作
    public void write()
    {
    start=true;
    count=10;
    
    }
    
    //写操作
    public void read()
    {
    if(start)
    {
    result=count*5;
    }
    System.out.println("result的值为"+result);
    }
    class ReadWriteThread extends Thread
    {
    private boolean state=false;
    
    public ReadWriteThread(boolean state)
    {
    this.state=state;
    }
    @Override
    public void run() {
    // TODO Auto-generated method stub
    if(state)
    {
    write();
    }
    else
    {
    read();
    }
    }
    }
    public static void main(String[] args) {
    SynchronizedDemo demo=new SynchronizedDemo();
    demo.new ReadWriteThread(true).start();
    demo.new ReadWriteThread(false).start();
    
    }
    }
    

     如果要每次都实现 result的值为50 怎么办呢?  很简单 就修改两处地方

    //读操作
    public  synchronized void write()
    {
    start=true;
    count=10;
    
    }
    
    //写操作
    public synchronized void read()
    {
    if(start)
    {
    result=count*5;
    }
    

    这只保证了可见性,我们还要保证先写后读 还要改一个就是

    public static void main(String[] args) {
    		SynchronizedDemo demo=new  SynchronizedDemo();
    		
    		demo.new ReadWriteThread(true ).start();
    		
    		try {
    			Thread.sleep(100);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		//休眠一下,不要让下面的读操作太快执行
    		demo.new ReadWriteThread(false).start();
    		
    		}
    

      

    那么每次运行结果都会输出 result的值为50   如果觉得有收获就点击 推荐,让更多人快速学习,不懂也可以私信我免费交流

  • 相关阅读:
    巧用border效果
    移动端页面无刷新跳转方法有三种
    word-break和word-wrap的使用和区别
    动态获取移动端视宽,从而结合rem达到适配
    一步一步学习IdentityServer4 (3)自定登录界面并实现业务登录操作
    一步一步学习IdentityServer3 (15) 授权模式那些事
    一步一步学习IdentityServer4 (2) 开始一个简单的事例
    一步一步学习IdentityServer4 (1) 概要配置说明
    Owin 自定义中间件(2)中间件进阶
    一步一步学习IdentityServer3 (14) 启用Https
  • 原文地址:https://www.cnblogs.com/imfjj/p/6109557.html
Copyright © 2020-2023  润新知