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

句容网站设计公司湖南产品网络推广业务

句容网站设计公司,湖南产品网络推广业务,做网站字号多大,安卓游戏模板下载网站文章目录 一、happens-before的定义二、happens-before的规则1. 程序顺序规则:2. 监视器锁规则:3. volatile变量规则:4. 传递性:5. start()规则:6. join()规则: 一、happens-before的定义 如果一个操作hap…

文章目录

  • 一、happens-before的定义
  • 二、happens-before的规则
    • 1. 程序顺序规则:
    • 2. 监视器锁规则:
    • 3. volatile变量规则:
    • 4. 传递性:
    • 5. start()规则:
    • 6. join()规则:

一、happens-before的定义

  • 如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。
  • 两个操作之间存在happens-before关系,并不意味着Java平台的具体实现必须要按照 happens-before关系指定的顺序来执行。如果重排序之后的执行结果,与按happens-before关系来执行的结果一致,那么这种重排序并不非法

二、happens-before的规则

1. 程序顺序规则:

一个线程中的每个操作,happens-before于该线程中的任意后续操作。

程序顺序规则(Program Order Rule)指的是在单个线程内,按照程序的顺序,前面的操作 happens-before 后面的操作。这意味着一个线程中的每个操作都会在该线程中的任意后续操作之前发生。

下面是一个简单的Java程序示例,展示了程序顺序规则的应用:

public class ProgramOrderDemo {private int count = 0;public void increment() {count++; // 操作1}public void printCount() {System.out.println("Count: " + count); // 操作2}public static void main(String[] args) {ProgramOrderDemo demo = new ProgramOrderDemo();Thread thread1 = new Thread(() -> {demo.increment(); // 线程1中的操作1demo.printCount(); // 线程1中的操作2});Thread thread2 = new Thread(() -> {demo.increment(); // 线程2中的操作1demo.printCount(); // 线程2中的操作2});thread1.start();thread2.start();}
}

在上述示例中,我们创建了两个线程:thread1和thread2,它们都会调用ProgramOrderDemo类中的increment()和printCount()方法。

根据程序顺序规则,线程1中的操作1(count++)happens-before 线程1中的操作2(System.out.println("Count: " + count)),同样线程2中的操作1(count++)happens-before 线程2中的操作2(System.out.println("Count: " + count))。

这意味着在每个线程中,count++操作一定会在System.out.println("Count: " + count)操作之前发生。因此,我们可以确保在每个线程中打印的count值是递增的。

请注意,尽管两个线程并行执行,但由于程序顺序规则的存在,各个线程内部的操作顺序是有序的,不会出现线程间的竞争条件。

2. 监视器锁规则:

对一个锁的解锁,happens-before于随后对这个锁的加锁。

监视器锁规则(Monitor Lock Rule)指的是对一个锁的解锁操作 happens-before 于随后对同一个锁的加锁操作。这个规则确保了在多线程环境下,对共享资源的同步访问。

下面是一个简单的Java程序示例,展示了监视器锁规则的应用:

public class MonitorLockDemo {private int count = 0;private Object lock = new Object();public void increment() {synchronized (lock) {count++; // 线程1中的操作1}}public void printCount() {synchronized (lock) {System.out.println("Count: " + count); // 线程2中的操作2}}public static void main(String[] args) {MonitorLockDemo demo = new MonitorLockDemo();Thread thread1 = new Thread(() -> {demo.increment(); // 线程1中的操作1});Thread thread2 = new Thread(() -> {demo.printCount(); // 线程2中的操作2});thread1.start();thread2.start();}
}

在上述示例中,我们创建了两个线程:thread1和thread2,它们都会调用MonitorLockDemo类中的increment()和printCount()方法。在这个类中,我们使用了一个对象lock作为锁。

根据监视器锁规则,线程1中的操作1(count++)happens-before 线程2中的操作2(System.out.println("Count: " + count))。

这意味着在线程1中,对锁的解锁操作一定会在线程2中对同一个锁的加锁操作之前发生。因此,我们可以确保在执行打印操作时,count的值是线程1已经更新过的。

请注意,通过使用synchronized关键字和共享的锁对象,我们确保了对count的访问是同步的,避免了竞态条件和数据不一致的问题。这是因为监视器锁规则确保了解锁操作 happens-before 加锁操作,从而确保了对共享资源的正确同步访问。

3. volatile变量规则:

对一个volatile域的写,happens-before于任意后续对这个volatile域的读。

volatile变量规则(Volatile Variable Rule)指的是对一个volatile域的写操作 happens-before 于任意后续对这个volatile域的读操作。这个规则确保了在多线程环境下,对volatile变量的可见性和顺序性。

下面是一个简单的Java程序示例,展示了volatile变量规则的应用:

public class VolatileVariableDemo {private volatile int number = 0;public void writeNumber() {number = 42; // 写操作}public void readNumber() {System.out.println("Number: " + number); // 读操作}public static void main(String[] args) {VolatileVariableDemo demo = new VolatileVariableDemo();Thread thread1 = new Thread(() -> {demo.writeNumber(); // 写操作});Thread thread2 = new Thread(() -> {demo.readNumber(); // 读操作});thread1.start();thread2.start();}
}

在上述示例中,我们创建了两个线程:thread1和thread2,它们都会调用VolatileVariableDemo类中的writeNumber()和readNumber()方法。在这个类中,我们使用了一个volatile修饰的变量number。

根据volatile变量规则,线程1中的写操作(number = 42)happens-before 线程2中的读操作(System.out.println("Number: " + number))。

这意味着在线程1中,对number的写操作一定会在线程2中对同一个number的读操作之前发生。因此,我们可以确保在执行打印操作时,读取到的number的值是线程1已经写入的。

请注意,使用volatile修饰变量可以保证其在多线程环境下的可见性和顺序性。这意味着对volatile变量的写操作对其他线程是可见的,并且读操作一定会读取到最新的值。这是因为volatile变量规则确保了对volatile变量的写 happens-before 于任意后续对这个volatile变量的读。

4. 传递性:

如果A happens-before B,且B happens-before C,那么A happens-before C。

下面是一个新的示例,展示了happens-before关系的传递性:

public class TransitivityDemo {private int number = 0;private volatile boolean ready = false;public void writer() {number = 42; // 写操作ready = true; // 写操作}public void reader() {if (ready) { // 读操作System.out.println("Number: " + number); // 读操作}}public static void main(String[] args) {TransitivityDemo demo = new TransitivityDemo();Thread thread1 = new Thread(() -> {demo.writer(); // 写操作});Thread thread2 = new Thread(() -> {demo.reader(); // 读操作});thread1.start();thread2.start();}
}

在这个示例中,我们有一个TransitivityDemo类,其中包含一个number变量和一个ready变量。在writer()方法中,我们首先进行写操作number = 42,然后进行写操作ready = true。在reader()方法中,我们进行读操作if (ready),如果ready为true,则进行读操作System.out.println("Number: " + number)。

根据happens-before关系的传递性,线程1中的写操作number = 42 happens-before 线程1中的写操作ready = true。同时,线程1中的写操作ready = true happens-before 线程2中的读操作if (ready)。因此,我们可以得出结论,线程1中的写操作number = 42 happens-before 线程2中的读操作if (ready)。

由于happens-before关系的传递性,我们可以得出A happens-before C的结论,即线程1中的写操作number = 42 happens-before 线程2中的读操作System.out.println("Number: " + number)。

这个示例演示了happens-before关系的传递性,其中A happens-before B,B happens-before C,因此A happens-before C。

5. start()规则:

如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的 ThreadB.start()操作happens-before于线程B中的任意操作。

当线程A执行ThreadB.start()方法启动线程B时,根据Java内存模型(Java Memory Model,JMM)中的start()规则,线程A的ThreadB.start()操作将happens-before于线程B中的任意操作。这意味着线程B中的任意操作都可以看到线程A在调用ThreadB.start()之前的操作。

下面是一个简单的示例代码来展示这个规则:

public class ThreadDemo {private static boolean ready = false;public static void main(String[] args) throws InterruptedException {ThreadB threadB = new ThreadB();Thread threadA = new Thread(() -> {System.out.println("Thread A is doing some work");ready = true;threadB.start(); // 线程A启动线程B});threadA.start(); // 启动线程AthreadA.join(); // 等待线程A执行完毕System.out.println("Thread B is ready? " + threadB.isReady());}static class ThreadB extends Thread {public boolean isReady() {return ready;}@Overridepublic void run() {System.out.println("Thread B is running");// 在这里可以看到线程A在调用ThreadB.start()之前的操作System.out.println("Thread B sees ready? " + ready);}}
}

在这个示例中,线程A首先会执行一些工作,并将ready属性设置为true。然后,线程A调用threadB.start()来启动线程B。在线程B的run()方法中,我们可以看到线程A在调用ThreadB.start()之前的操作,即输出Thread B sees ready? true。

因此,根据start()规则,线程A的ThreadB.start()操作happens-before于线程B中的任意操作,确保了对ready属性的修改对线程B可见。

运行结果如下:
happens-before

6. join()规则:

如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作 happens-before于线程A从ThreadB.join()操作成功返回。

根据Java内存模型(Java Memory Model,JMM)中的join()规则,如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。这意味着线程A能够看到线程B在join()之前的操作。

下面是一个简单的示例代码来展示这个规则:

public class ThreadDemo {private static boolean ready = false;public static void main(String[] args) throws InterruptedException {ThreadB threadB = new ThreadB();Thread threadA = new Thread(() -> {System.out.println("Thread A is doing some work");threadB.start(); // 线程A启动线程Btry {threadB.join(); // 线程A等待线程B执行完毕} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread A sees ready? " + ready);});threadA.start(); // 启动线程AthreadA.join(); // 等待线程A执行完毕System.out.println("Thread B is ready? " + threadB.isReady());}static class ThreadB extends Thread {public boolean isReady() {return ready;}@Overridepublic void run() {System.out.println("Thread B is running");ready = true; // 在这里修改ready属性}}
}

在这个示例中,线程A首先会执行一些工作,并启动线程B。然后,线程A调用threadB.join()来等待线程B执行完毕。在线程B的run()方法中,我们将ready属性设置为true。

当线程A从threadB.join()成功返回后,它能够看到线程B在join()之前的操作。因此,线程A输出的Thread A sees ready? true将显示线程B在join()之前将ready属性设置为true。

因此,根据join()规则,线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回,确保了对ready属性的修改对线程A可见。

运行结果:
happens-before

http://www.tj-hxxt.cn/news/108869.html

相关文章:

  • 青海微信网站建设北京做百度推广的公司
  • 眉山 网站开发今天的最新消息新闻
  • 做网站怎么添加图片百度搜索关键词数据
  • 山东省住房和城乡建设部网站首页建个人网站的详细步骤
  • 安卓手机做网站服务器seo管理系统培训运营
  • 公司做网站注意什么最新国际新闻热点事件
  • 常州网站建设平台游戏推广代理加盟
  • 龙冠专业网站建设长沙哪家网络公司做网站好
  • 橘子建站app推广兼职是诈骗吗
  • 河北网站建设报价环球网广东疫情最新消息
  • 重庆南坪网站建设公司b站视频推广的方法有哪些
  • 网站建设技术解决方案宁波pc营销型网站制作
  • 滨州正规网站建设公司百度竞价排名是哪种方式
  • 网站开发中遇到的技术问题免费网站建设制作
  • 开网站建设工作是如何万能bt搜索引擎
  • 高校建设主流网站奶茶推广软文200字
  • 做网站费用会计分录怎么做手机打开国外网站app
  • 郑州航海路附近网站建设公司上海网络营销有限公司
  • 二手车网站开发过程sem是什么的英文缩写
  • 专业做毕业设计网站设计2345网址导航 中国最
  • 网站建设 源码永久免费google搜索引擎
  • 做一个企业网站需要多长时间网站建设纯免费官网
  • 龙华做棋牌网站建设找哪家效益快查关键词的排名工具
  • 连云港网站关键词优化服务小广告网页
  • 做网站哪家南京做网站怎么创建个人网站
  • 网站建设与规划心得体会seo外链要做些什么
  • 网址大全360太原seo代理商
  • 本地安装网站免费发布产品信息的网站
  • 傻瓜式网站制作软件关键词优化seo费用
  • 重庆建筑工程网站超级优化大师下载