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

石家庄网站建设哪家好深圳广胜达建设公司

石家庄网站建设哪家好,深圳广胜达建设公司,北京智能网站建设平台,网络公司具体是干什么的文章目录 并发编程中的三个问题可见性原子性有序性 了解Java内存模型JMMsynchronized 保证三大特性synchronized 保证原子性synchronized 保证可见性synchronized 保证有序性 synchronized 的特性可重入特性不可中断特性 通过反汇编学习synchronized原理当修饰代码块时当修饰方… 文章目录 并发编程中的三个问题可见性原子性有序性 了解Java内存模型JMMsynchronized 保证三大特性synchronized 保证原子性synchronized 保证可见性synchronized 保证有序性 synchronized 的特性可重入特性不可中断特性 通过反汇编学习synchronized原理当修饰代码块时当修饰方法时 通过JVM源码学习synchronizedmonitor 监视器锁monitor竞争monitor等待monitor释放 并发编程中的三个问题 可见性 是指一个线程对共享变量进行修改另一个先立即得到修改后的最新值 演示可见性问题 实际效果线程 1 并没有退出循环说线程二修改了flag的值而线程一并没有立即得到修改后的值。 原子性 原子性Atomicity在一次或多次操作中要么所有的操作都执行并且不会受其他因素干扰而中断要么所有的操作都不执行。 演示原子性问题 执行几次后的实际结果 证明 number 实际上是一个复合操作且是非原子性的它包含三个步骤 读取 number 的当前值。将读取的值加1。将结果写回到 number。 再通过反汇编说明number的问题 javap -p -v .\AtomicityDemo 其中对于number 而言number 为静态变量实际会产生如下的 JVM 字节码指令 number 一共由于4条命令构成 getstatic获取到当前 number 的值iconst_1准备常量 1iadd当前值与 iconst_1 做加法putstatic将结果赋值给 number 以上多条指令在一个线程的情况下是不会出问题的但是在多线程环境下就可能会出现问题。比如一个线程在执行 13: iadd 时另一个线程又执行 9: getstatic。会导致两次 number实际上只加了1。 有序性 是指程序代码在执行过程中的先后顺序由于Java在编译期以及运行期的优化导致了代码的执行顺序未必就是开发者编写代码时的顺序。 举个例子 int a 1; // 操作1 int b 2; // 操作2// 重排序后 int b 2; // 操作2 int a 1; // 操作1出现可见性问题的两个前提至少有两个线程、有个共享变量 public class Ordering {private int num 0;private boolean flag false;private int x;public void action1() {if (flag) {x num num;} else {x 1;}// x的可能结果System.out.println(x);}public void action2() {num 2;flag true;} }x的可能结果 结果1线程1执行 action1()此时 flagfalsex的结果为1结果2线程2先执行了 action2()线程1再执行 action1()此时 flagtrue, num2x的结果为4结果3java在编译和运行时会对代码进行优化action2()的执行顺序变成了如下此时线程2更改flag值之后CPU切换到线程1执行num为初始化的值0x的结果为0 public void action2() { // 因为第2行和第3行代码并没有逻辑关系 Java在编译期以及运行期的优化 可能会将其改变顺序flag true;num 2; }上面的结果3就是有序性产出的并发问题 了解Java内存模型JMM Java内存模型Java Memory Model, JMM是Java虚拟机(JVM)定义的一种规范用于描述多线程程序中变量包括实例字段、静态字段和数组元素如何在内存中存储和传递的规则。规范了线程何时会从主内存中读取数据、何时会把数据写回主内存。 JMM 抽象了线程和主内存之间的关系就比如说线程之间的共享变量必须存储在主内存中。 JMM 的核心目标是确保多线程环境下的可见性、有序性和原子性从而避免由于硬件和编译器优化带来的不一致问题。 可见性确保一个线程对变量的修改能及时被其他线程看到。关键字 volatile 就是用来保证可见性的它强制线程每次读写时都直接从主内存中获取最新值。有序性指线程执行操作的顺序。JMM允许某些指令重排序以提高性能但会保证线程内的操作顺序不会被破坏并通过 happens-before 关系保证跨线程的有序性。原子性是指操作不可分割线程不会在执行过程中被中断。例如synchronized 关键字能确保方法或代码块的原子性。 从 JMM 了解可见性线程 1 将 a 的值拷贝一份并修改了 a 的值然后同步给主内存的值而线程 2 一直用的是副本的值并不知道主内存的值已被修改了所以线程 1 修改的值对于线程 2 来说是不可见的。 synchronized 保证三大特性 synchronized能够保证在同一时刻最多只有一个线程执行该段代码以达到保证并发安全的效果。 synchronized (锁对象) { // 受保护资源; }synchronized 保证原子性 synchronized保证原子性的原理synchronized保证只有一个线程拿到锁能够进入同步代码块。 案例演示:5个线程各执行1000次 i; public class Test01Atomicity {private static int number 0;public static void main(String[] args) throws InterruptedException {Runnable increment () - {for (int i 0; i 1000; i) {synchronized (Test01Atomicity.class) {number;}}};ArrayListThread ts new ArrayList();for (int i 0; i 50; i) {Thread t new Thread(increment);t.start();ts.add(t);}for (Thread t : ts) {t.join();}System.out.println(number number);} }对number;增加同步代码块后保证同一时间只有一个线程操number;。就不会出现安全问题。 synchronized 保证可见性 案例演示一个线程根据boolean类型的标记flag while循环另一个线程改变这个flag变量的值另一个线程并不会停止循环。 public class Test01Visibility {// 多个线程都会访问的数据我们称为线程的共享数据private static boolean run true;public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(() - {while (run) {// 增加对象共享数据的打印println是同步方法System.out.println(run run);}});t1.start();Thread.sleep(1000);Thread t2 new Thread(() - {run false;System.out.println(时间到线程2设置为false);});t2.start();} }点进去println本质还是加了 synchronized 关键字 synchronized 保证有序性 为什么要重排序 为了提高程序的执行效率编辑器和cpu会对程序中的代码进行重排序 as-if-serial语义 as-if-serial语义的意思是不管编译器和CPU如何重排序必须保证在单线程情况下程序的结果是正确的。 以下数据有依赖关系不能重排序。 写后读 int a 1; int b a;写后写 int a 1; int a 2;读后写 int a 1; int b a; int a 2;synchronized 后虽然进行了重排序保证只有一个线程会进入同步代码块也能保证有序性。 synchronized 保证有序性的原理加s ynchronized 后依然会发生重排序只不过我们有同步代码块可以保证只有一个线程执行同步代码中的代码。保证有序性。 synchronized 的特性 可重入特性 synchronized内部维护了一个计数器 recursions 变量记录线程是第几次获取锁在执行完同步代码块时计数器的数量会 - 1 直到计时器的数量为 0就释放这个锁。 好处1可以避免死锁 2可以让我们更好的来封装代码 不可中断特性 不可中断特性一个线程获得锁后另一个线程想要获得锁必须处于阻塞或等待状态如果第一个线程不释放锁第二个线程会一直阻塞或等待不可被中断。 public class Demo02_Uninterruptible {private static final Object obj new Object();public static void main(String[] args) throws InterruptedException {// 1.定义一个RunnableRunnable run () - {// 2.在Runnable定义同步代码块synchronized (obj) {String name Thread.currentThread().getName();System.out.println(name 进入同步代码块);// 保证不退出同步代码块try {Thread.sleep(888888);} catch (InterruptedException e) {e.printStackTrace();}}};// 3.先开启一个线程来执行同步代码块Thread t1 new Thread(run);t1.start();Thread.sleep(1000);// 4.后开启一个线程来执行同步代码块(阻塞状态)Thread t2 new Thread(run);t2.start();// 5.停止第二个线程System.out.println(停止线程前);t2.interrupt();System.out.println(停止线程后);System.out.println(t1.getState());System.out.println(t2.getState());} }执行结果 t1 线程不释放锁t2 线程会一直阻塞或等待既不可被中断。 通过反汇编学习synchronized原理 它的实现原理依赖与 JVM 中的 Monitor监视器锁和对象头Object Header。 当修饰代码块时 会在代码块的前后插入monitorenter和monitorexit字节码指令可以把monitorenter理解为加锁monitorexit理解为解锁。 第二次出现 monitorexit 可以理解为出现异常的情况也需要解锁。 monitorenter synchronized 的锁对象会关联一个 monitor这个 monitor 不是我们主动创建的是 JVM 的线程执行到这个同步代码块发现锁对象没有monitor 就会创建 monitormonitor 内部有两个重要的成员变量owner: 拥有 这把锁的线程recursions 会记录线程拥有锁的次数当一个线程拥有 monitor 后其他线程只能等待。 monitorexit 能执行 monitorexit 指令的线程一定是拥有当前对象的 monitor 的所有权的线程。执行 monitorexit 时会将 monitor 的进入数减 1。当 monitor 的进入数减为 0 时当前线程退出 monitor不再拥有 monitor 的所有权此时其他被这个 monitor 阻塞的线程可以尝试去获取这个 monitor的所有权。 当修饰方法时 方法的常量池会添加一个 ACC_SYNCHRONIZED 标识当某个线程访问这个方法时会检查是否有ACC_SYNCHRONIZED标识若有则需要获取监视器锁才可以执行方法此时就保证了方法的同步。 通过JVM源码学习synchronized monitor 监视器锁 在 HotSpot 虚拟机中 monitor 是通过 ObjectMonitor 实现的底层是 c 实现的其数据结构和解释如下 monitor竞争 通过CAS尝试把 monitor 的 owner 字段设置为当前线程。如果设置之前的 owner 指向当前线程说明当前线程再次进入monitor即重入锁执行 recursions 记录重入的次数。如果当前线程是第一次进入该 monitor设置 recursions 为 1_owner 为当前线程该线程成功获 得锁并返回。如果获取锁失败则等待锁的释放。 monitor等待 当前线程被封装成ObjectWaiter对象node状态设置成ObjectWaiter::TS_CXQ。在for循环中通过 CAS 把 node 节点 push 到 _cxq 列表中同一时刻可能有多个线程把自己的 node 节点 push 到_cxq列表中。node节点push到_cxq列表之后通过自旋尝试获取锁如果还是没有获取到锁则通过park将当 前线程挂起等待被唤醒。当该线程被唤醒时会从挂起的点继续执行通过ObjectMonitor::TryLock 尝试获取锁。 monitor释放 当某个持有锁的线程执行完同步代码块时会进行锁的释放给其它线程机会执行同步代码在 HotSpot中通过退出monitor的方式实现锁的释放并通知被阻塞的线程。 退出同步代码块时会让_recursions 减 1当 recursions 的值减为0时说明线程释放了锁。根据不同的策略由QMode指定从cxq或EntryList中获取头节点通过 ObjectMonitor::ExitEpilog 方法唤醒该节点封装的线程唤醒操作最终由unpark完成。
http://www.hkea.cn/news/14525894/

相关文章:

  • 网站导航漂浮代码如意宝魔方建站
  • 网站建设和网站设计一样吗该网站正在紧急升级维护中
  • 网站ar怎么做哈尔滨人才招聘信息网
  • 专门做各种产品测评的网站5g互联如何取消网站备案
  • 做移动网站首页软网站怎么做外链
  • 视频网站焦点图郑州百度推广公司地址
  • 西安做网站朋朋有用免费模板网
  • 财经网站源码 织梦wiki wordpress
  • 企业做网站优劣网络运营者应当为()
  • 网站建设 统一质量标准企业网站优化软件
  • 网站做百度排名教程wordpress文章页特色
  • 厦门海沧建设局网站做网站的步骤 优帮云
  • 网站开发后如何维护seo是什么姓
  • 做网站做的网页开发价格
  • 做关于什么的网站做网站策划书
  • 湘潭高端网站建设如何做公众号微信
  • 做网站需要什么代码网站域名空间地址
  • 英德建设局网站山东省建设科技协会网站
  • 做微课的网站有哪些方面办公室装修设计方案范本
  • 购买的网站平台建设服务计入广州网站制作知名 乐云践新
  • 手机网站制作注意事项婚庆策划公司的商业模式
  • 昌平石家庄网站建设外贸网站建设的好处
  • 如何检测网站是否安全网站建设商务通什么意思
  • 网站集约化建设报告深圳网络推广最新招聘
  • 福州网站设计网址网站服务费网络建设会计分录
  • 买公司的网站建设白头鹰网站一天可以做多少任务
  • 做问卷调查赚钱的网站好泊头在哪做网站比较好
  • 陵园网站建设价格网站建设报价表模板
  • 花店网站建设规划书上海网站建设平台站霸网络
  • 关于网站设计的新闻wordpress4.9主题安装