java中Volatile的工作原理就像,如果我们希望我们的对象同时被多个线程访问,我们可以使用这个关键字。这个关键字是使我们的类、代码、方法线程安全的另一种方式,这意味着多个线程可以毫无问题地访问同一资源。我们的意思是违反关键字表明我们可以说多个线程将同时操作该变量值。
开始您的免费软件开发课程
网络开发、编程语言、软件测试及其他
如果你想让你的代码线程安全,你可以使用violations关键字。此外,它还提供同步功能;在这种情况下,这是一个不错的选择。
我们使用此关键字声明的任何变量都不会进入缓存;我们执行的所有操作,例如读取和写入,都将进入主内存。
class DemoSharedObject { static int sharedresources = 10; }
下面一种导致数据不一致的情况:
我们有一个名为 DemoSharedObject 的类,假设有多个线程正在处理该类并修改类成员的值。因此,如果我们有多个线程在不同的处理器上运行,则每个线程都有自己的本地复制资源。因此,如果某个线程修改了公共资源的值,它的值不会很快反映到主内存中。但在这种情况下,我们的其他线程不知道共享资源的当前值,因此这将导致数据不一致的问题。
在java中,我们有两种东西:同步语句和同步方法。
在这种情况下,我们只需将synchronized关键字添加到方法签名中即可。
语法:
public synchronized return_type method_name(){}
示例:
public class Demosynchronized { private int c = 0; public synchronized void method1() { c++; } public synchronized void method2() { c--; } public synchronized int method3() { return c; } }
在上面的例子中,我们只是增加和减少计数器,但我们必须在方法中引入一个synchronized关键字,这样就不会出现数据不一致的情况,并且所有线程都会收到更新后的值。
因此,当第一个线程在 method1() 上进行处理时,所有其他线程将被阻塞(挂起);在工作线程已经获得该对象的锁之前,没有其他线程可以访问同一对象。这就是他们避免数据不一致的方法。
此外,现在还有更多的事情是,每当线程完成对 method1() 的操作,即完成执行一个方法时,它就会与其他线程建立关系,因此对象值或状态的变化是可见的也到其他线程。
语法:
synchronized(){}
示例:
public void demo(String namestr) { synchronized(this) { lastName = namestr; count++; } list.add(namestr); }
在上面的示例中,我们有一个同步块将为我们管理数据。就像 namestr 将通过 demo() 方法同步一样。也就是我们要同步的数据;我们只需要将它们放入这个块中即可。
因此,当我们有两个线程在同一个对象上进行写入和读取时,这意味着我们有多个线程正在访问同一个对象以进行读取和写入,那么我们应该使用 Viruss 关键字,因为它没有为我们提供保证线程阻塞,除非并且直到其他线程停止执行,所以在这种情况下,我们应该进行同步,因为它为我们提供了一些比违反关键字更多的功能,例如:
它可以与方法一起使用,也可以与语句块一起使用,这意味着我们不需要同步整个方法;我们也可以在要同步的块内编写代码。
当我们读取或写入 volatile 变量的值时,它们直接将值读取或写入主内存,这不是一个好的做法,而且与缓存相比,这也很昂贵。因此,在使用 volatile 关键字之前请三思;它会直接影响你的表现。
假设我们有多个线程,它们不依赖于彼此的响应,这意味着读取和写入是彼此独立的,在这种情况下可以使用 volatile 关键字。但我们还有一种不适合使用 volatile 关键字的情况,如下所述:
Suppose thread has generated the first value of the volatile variable, and this current value will be used further to generate the new volatile variable values; in this case, this volatile keyword is not a good fit to generate the correct result; this condition will lead to a race condition were all thread going to read the same value but generate the new value for them and write the value to main memory and override each other values, so this will leads to the wrong result, or we can say data inconsistency issue, so here volatile keyword is not good enough to avoid this case we have to move to synchronization where we have to types to make our code synchronized, i.e. synchronized method and synchronized statement.
Code:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TvvApplication { private static final Logger LOGGER = LoggerFactory.getLogger(TvvApplication.class); private static final Object aclock = new Object(); private static final Object aclock1 = new Object(); private static volatile int MY_INT = 0; public static void main(String[] args) { System.out.println("without block"); System.out.println("with block calling static method :: "); testBlock(); } static void testBlock1() { synchronized (aclock1) { MY_INT = MY_INT + 1; System.out.println( Thread.currentThread().getName() +"new lock we create and printing voilatile value using block for block one:: "+ MY_INT); } } static void testBlock() { synchronized (aclock) { MY_INT = MY_INT + 1; System.out.println( Thread.currentThread().getName() +"new lock we create and printing voilatile value using block for block two:: "+ MY_INT); } } }
Output :
<img src="https://img.php.cn/upload/article/000/000/000/172500598784733.png" alt="java中的Volatile关键字" >
So this can provide thread safety when data does not depend on each other; if data depends, we should go for synchronization.
以上是java中的Volatile关键字的详细内容。更多信息请关注PHP中文网其他相关文章!