在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中实现可见性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MyBatisPlus的简介及案例详解

    MyBatisPlus的简介及案例详解

    MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率。本文将为大家详细介绍一下MyBatisPlus是使用,需要的可以参考一下
    2022-07-07
  • Java中的Lombok使用详解

    Java中的Lombok使用详解

    这篇文章主要介绍了Java中的Lombok使用详解,Lombok是一个在Java开发过程中使用注解的方式,用于简化JavaBean的编写,避免冗余和样板式代码的插入,使类的编写更加简洁,需要的朋友可以参考下
    2023-08-08
  • Java实现ATM银行管理系统(控制台版本)

    Java实现ATM银行管理系统(控制台版本)

    这篇文章主要为大家详细介绍了如何利用Java语言实现控制台版本的ATM银行管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • Java日期时间类及计算详解

    Java日期时间类及计算详解

    这篇文章主要介绍了Java日期时间类及计算详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下,希望对你的学习有所帮助
    2022-07-07
  • Spring mvc拦截器实现原理解析

    Spring mvc拦截器实现原理解析

    这篇文章主要介绍了Spring mvc拦截器实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Java使用递归回溯完美解决八皇后的问题

    Java使用递归回溯完美解决八皇后的问题

    这篇文章主要介绍了Java基于循环递归回溯实现八皇后问题算法,结合具体实例形式分析了java的遍历、递归、回溯等算法实现八皇后问题的具体步骤与相关操作技巧,需要的朋友可以参考下
    2021-11-11
  • 怎样通过反射获取非静态内部类实例

    怎样通过反射获取非静态内部类实例

    这篇文章主要介绍了怎样通过反射获取非静态内部类实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • java与c#的语法区别详细介绍

    java与c#的语法区别详细介绍

    由C#转入Java一段时间了,总结下个人认为的Java同C#语法之间的不同之处,有不同意见之处还望各位海涵,刚学Java时觉得语法同C#大致是相同的(应该说C#同Java大致相同
    2012-11-11
  • Java框架入门之简单介绍SpringBoot框架

    Java框架入门之简单介绍SpringBoot框架

    今天给大家带来的是关于Java的相关知识,文章围绕着SpringBoot框架展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • JavaSwing FlowLayout 流式布局的实现

    JavaSwing FlowLayout 流式布局的实现

    这篇文章主要介绍了JavaSwing FlowLayout 流式布局的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12

最新评论