
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
我们在前几期的文章中给大家简单介绍了软件开发项目中内存模型的概念与应用基础知识等内容,而本文我们就再来了解一下,java编程内存模型应用分析。
JMM是通过各种操作来定义,包括对变量的读写操作,监视器monitor的加锁和释放操作,以及线程的启动和合并操作,JMM为程序中所有的操作定义了一个偏序关系,称为Happens-before,要想保证执行操作B的线程看到A的结果(无论A和B是否在同一个线程中执行),那么A和B之间必须满足Happens-before关系。如果没有这个关系,那么JVM可以对他们任意的重排序。
当一个变量被多个线程读取并且至少被一个线程写入时,如果在读操作和写操作之间没有依照Happens-before来排序,那么就会产生数据竞争的问题。在正确使用同步的程序中不存在数据竞争,并会表现出串行一致性,这意味着程序中的所有操作都会按照一种固定的和全局的顺序执行。
由于Happens-Before的排序功能很强大,因此有时候可以”借助(Piggyback)”现有同步机制的可见性属性。这需要将Happens-Before的程序规则与其他某个顺序规则(通常是监视器锁规则或者volatile变量规则)结合起来,从而对某个未被锁保护的变量的访问操作进行排序。这项技术由于对语句的顺序非常敏感,因此很容易出错。他是一项高级技术,并且只有当需要大限度地提升某些类(例如ReentrantLock)的性能时,才应该使用这项技术。同时,因为在使用中很容易出错,因此也要谨慎使用。
之所以将这项技术称为“借助”,是因为它使用了一种现有的Happens-Before顺序来确保对象X的可见性,而不是专门为了发布X而创建一种Happens-Before顺序。在类库中提供的其他Happens-Before排序包括:
将一个元素放入一个线程安全容器的操作将在另一个线程从该容器中获得这个元素的操作之前执行
在CountDownLatch上的倒数操作将在线程从闭锁上的await方法返回之前执行
释放Semaphore许可的操作将在从该Semaphore上获得一个许可之前执行
Future表示的任务的所有操作将在从Future.get中返回之前执行
向Executor提交一个Runnable或Callable的操作将在任务开始执行之前执行
一个线程到达CyclicBarrier或Exchange的操作将在其他到达该栅栏或交换点的线程被释放之前执行。如果CyclicBarrier使用一个栅栏操作,那么到达栅栏的操作将在栅栏操作之前执行,而栅栏操作又会在线程从栅栏中释放之前执行。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。