linux网站开发电子商务网站数据库建设
news/
2025/10/4 14:14:34/
文章来源:
linux网站开发,电子商务网站数据库建设,wordpress 文章点赞功能,wordpress修改固定链接打不开这里我们使用Java的线程与锁来解析共享内存模型#xff1b;做过java开发并且了解线程安全问题的知道#xff0c;要使某段代码是线程安全的那必须要满足两个条件#xff1a;内存可见性、原子性#xff1b; 内存可见性 在JVM规定多个线程进行通讯是通过共享变量进行的做过java开发并且了解线程安全问题的知道要使某段代码是线程安全的那必须要满足两个条件内存可见性、原子性 内存可见性 在JVM规定多个线程进行通讯是通过共享变量进行的而Java内存模型规定了有主内存是所有线程共享的而各个线程又有自己的工作内存线程只能访问自己的工作内存中数据 如有一个共享变量x两个线程a、b变量x存储在主内存中然后又两个x的拷贝分别存储在a、b线程的工作内存中线程a、b只能对自己工作内存中的x的拷贝进行操作不可直接操作主内存 线程a对x修改时先把值放到自己的工作内存中然后再把工作内存中的x拷贝更新到主内存中线程b同样如此当线程a更新了主内存后线程b刷新工作内存后就能看到a更新后的最新值这就是内存可见性问题 内存可见性要保证两点1、线程修改后的共享变量更新到主内存2、从主内存中更新最新值到工作内存中 内存可见性线程对共享变量的修改其他线程可以看到修改后的值 原子性 当线程引用共享变量时工作内存中没有共享变量时它会从主内存复制共享变量到自己工作内存中当工作内存有共享变量时线程可能会从主内存更新也有可能直接使用工作内存中的共享变量有代码块,count为共享变量 1 count;
// count初始值为0这时有a、b线程都执行这行代码可能有不少人以为线程a , b执行完成后count的值为2但真实情况是count最终值可能为1也可能为2因为这里有一个原子性问题 熟悉Java的都知道在Java中count非原子操作流程为 1、把主内存共享变量count拷贝到工作内存 2、把工作内存中count值1 3、把结果写回更新回主内存 当只有一个线程时这个操作没有问题 当有多个线程时有可能出现 1、 线程a把主内存共享变量count拷贝到工作内存 2、 线程b把主内存共享变量count拷贝到工作内存 3、 线程a把工作内存中count进行1 4、 线程b把工作内存中count进行1 5、 线程a把工作内存更新到主内存 6、 线程b把工作内存更新到主内存 a,b线程执行完后最终count的值只是1而不是我们期望得到的2因为这里出现了多个线程交叉执行导致破坏了程序的有序性而且count1操作又不是原子的所以我们必须要保证这程序的原子性可以使用Java中的synchronized同步或Lock机制来解决 使用共享内存模型进行并发编程时必须要解决我们上面介绍的两个点内存可见性、原子性但现在大部分编程语言原生都支持共享内存模型方式的并发所以我们很容易就可以达到这两个要求 现在代码的执行要经过多层的优化对指令重排序如编译器、处理器等级别的优化经过这些优化重排序后最终代码执行顺序可能与之前是不一致的在单线程时中编译器、处理会保持as-if-serial对不存在数据依赖的进行重排序所以不会出现重排序问题但在多线程情况下就会出现问题不过还好Java中有些机制可以使程序在编译器、处理器优化时会对有数据依赖的禁止指令重排序如volatile、synchronized等所以我们可以很轻松应对这问题 指令重排序问题 在Java中我们要使代码在多线程中同时满足内存可见性与有序性那就要使用Java提供给我们的同步与锁机制如synchronized、volatile、Lock、concurrent类等 优点共享内存模型线程与锁可以说是最常见的并发模型大多数编程语言都原生支持也适合解决很多问题通过线程与锁实现起来相对也简单点 缺点通过多线程实现并发而线程耗费的资源比较多线程总数有限制通过共享内存来实现多线程通讯又会涉及到锁、竟态、死锁等问题影响程序性能一不小心就会陷入可见性问题、重排序问题等而且多线程程序不容易测试、维护等 文章首发地址Solinxhttp://www.solinx.co/archives/179转载于:https://www.cnblogs.com/softlin/p/4474838.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/927211.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!