在Java中实现可见性(visibility)的主要方法详解

 更新时间:2023年08月07日 08:48:11   作者:Blue92120  
这篇文章主要介绍了在Java中实现可见性(visibility)的主要方法详解,在Java中,使用关键字volatile和使用锁(如synchronized关键字或 java.util.concurrent包中的锁)来确保对共享变量的修改在多线程环境中能够正确地被其他线程所观察到,需要的朋友可以参考下

可见性 visibility

在Java中,实现可见性(visibility)的主要方法是使用关键字volatile和使用锁(如synchronized关键字或 java.util.concurrent包中的锁)来确保对共享变量的修改在多线程环境中能够正确地被其他线程所观察到。

下面详细说明这两种方法,并附带代码演示。

1.使用volatile关键字:

volatile是一种轻量级的同步机制,用于告诉JVM对被修饰的变量不进行缓存,直接从主内存中读取和写入数据。

这样可以确保当一个线程修改了变量的值时,其他线程能够立即看到这个变化,而不是使用缓存中的旧值。

public class VolatileVisibilityExample {
    private volatile boolean flag = false;
    public void setFlag(boolean value) {
        flag = value;
    }
    public void checkFlag() {
        while (!flag) {
            // Busy waiting until the flag becomes true
        }
        System.out.println("Flag is now true!");
    }
    public static void main(String[] args) {
        VolatileVisibilityExample example = new VolatileVisibilityExample();
        new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            example.setFlag(true);
        }).start();
        new Thread(() -> {
            example.checkFlag();
        }).start();
    }
}

在上面的例子中,我们创建了一个VolatileVisibilityExample类,其中的flag变量被声明为volatile。

第一个线程在启动后会等待1秒钟然后将flag设置为true,而第二个线程在flag变为true之前会一直进行忙等待(busy waiting)。

由于flag是volatile的,第二个线程能够看到第一个线程对flag的修改,并在flag变为true时结束忙等待。

2.使用锁:

另一种实现可见性的方法是使用锁,通过synchronized关键字或者java.util.concurrent包中的锁机制来保护对共享变量的访问。

public class LockVisibilityExample {
    private boolean flag = false;
    private final Object lock = new Object();
    public void setFlag(boolean value) {
        synchronized (lock) {
            flag = value;
        }
    }
    public void checkFlag() {
        synchronized (lock) {
            while (!flag) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("Flag is now true!");
    }
    public static void main(String[] args) {
        LockVisibilityExample example = new LockVisibilityExample();
        new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            example.setFlag(true);
            synchronized (example.lock) {
                example.lock.notifyAll();
            }
        }).start();
        new Thread(() -> {
            example.checkFlag();
        }).start();
    }
}

在上面的例子中,我们创建了一个LockVisibilityExample类,其中使用了一个名为lock的对象作为锁。

在setFlag和checkFlag方法中,我们使用synchronized关键字来保护对flag的访问。

第一个线程设置flag为true并通过synchronized块的notifyAll()方法通知第二个线程,而第二个线程则在flag变为true之前一直等待,并在被通知后结束等待。

这两种方法都可以实现可见性,但使用volatile更为简单和轻量级。

然而,在某些情况下,使用锁可能会更有优势,例如需要进行更复杂的操作或需要更精细地控制对共享资源的访问。

到此这篇关于在Java中实现可见性(visibility)的主要方法详解的文章就介绍到这了,更多相关Java中实现可见性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java静态内部类实现单例过程

    Java静态内部类实现单例过程

    这篇文章主要介绍了Java静态内部类实现单例过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • 浅谈Spring自定义注解从入门到精通

    浅谈Spring自定义注解从入门到精通

    这篇文章主要介绍了浅谈Spring自定义注解从入门到精通,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • 关于@Autowierd && @Resource 你真的了解吗

    关于@Autowierd && @Resource 你真的了解吗

    这篇文章主要介绍了关于@Autowierd && @Resource的具体使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Android图片转换器代码分享

    Android图片转换器代码分享

    本文给大家总结了下在安卓程序中进行图片转换的方法,非常的实用,小伙伴们可以参考下。
    2015-10-10
  • java  Vector和ArrayList的分析及比较

    java Vector和ArrayList的分析及比较

    这篇文章主要介绍了java Vector和ArrayList的分析及比较的相关资料,Vector是多线程安全的,而ArrayList不是,本文主要做对比对这两个方法,需要的朋友可以参考下
    2016-11-11
  • java开发CPU流水线与指令乱序执行详解

    java开发CPU流水线与指令乱序执行详解

    这篇文章主要为大家介绍了java开发CPU流水线与指令乱序执行详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Java数组索引异常产生及解决方案

    Java数组索引异常产生及解决方案

    这篇文章主要介绍了Java数组索引异常产生及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • 举例讲解Java的Spring框架中AOP程序设计方式的使用

    举例讲解Java的Spring框架中AOP程序设计方式的使用

    这篇文章主要介绍了Java的Spring框架中AOP程序设计方式的使用讲解,文中举的AOP下抛出异常的例子非常实用,需要的朋友可以参考下
    2016-04-04
  • java定时器timer的使用方法代码示例

    java定时器timer的使用方法代码示例

    这篇文章主要介绍了java定时器timer的使用方法代码示例,向大家分享了两部分代码,详细内容请参见正文,还是比较不错的,需要的朋友可以参考下。
    2017-11-11
  • JAVA8 lambda表达式权威教程

    JAVA8 lambda表达式权威教程

    本文主要给大家讲解Java8中最重要的一个特征之一lambda表达式,本文通过实例图文解说给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习下吧
    2021-05-05

最新评论