volatile Keyword in Java
Using volatile is yet another way (like synchronized, atomic wrapper) of making class thread-safe. Thread-safe means that a method or class instance can be used by multiple threads at the same time without any problem. Consider the below example.
class SharedObj < // Changes made to sharedVar in one thread // may not immediately reflect in other thread static int sharedVar = 6; >
Suppose that two threads are working on SharedObj. If two threads run on different processors each thread may have its own local copy of sharedVariable. If one thread modifies its value the change might not reflect in the original one in the main memory instantly. This depends on the write policy of cache. Now the other thread is not aware of the modified value which leads to data inconsistency.
The below diagram shows that if two threads are run on different processors, then the value of sharedVariable may be different in different threads.
Note that writing of normal variables without any synchronization actions, might not be visible to any reading thread (this behavior is called sequential consistency). Although most modern hardware provides good cache coherence, therefore, most probably the changes in one cache are reflected in another but it’s not a good practice to rely on hardware to ‘fix’ a faulty application.
Note that volatile should not be confused with the static modifier. static variables are class members that are shared among all objects. There is only one copy of them in the main memory.
volatile vs synchronized: Before we move on let’s take a look at two important features of locks and synchronization.
- Mutual Exclusion: It means that only one thread or process can execute a block of code (critical section) at a time.
- Visibility: It means that changes made by one thread to shared data are visible to other threads.
Java’s synchronized keyword guarantees both mutual exclusion and visibility. If we make the blocks of threads that modify the value of the shared variable synchronized only one thread can enter the block and changes made by it will be reflected in the main memory. All other threads trying to enter the block at the same time will be blocked and put to sleep.
In some cases, we may only desire visibility and not atomicity. The use of synchronized in such a situation is overkill and may cause scalability problems. Here volatile comes to the rescue. Volatile variables have the visibility features of synchronized but not the atomicity features. The values of the volatile variable will never be cached and all writes and reads will be done to and from the main memory. However, the use of volatile is limited to a very restricted set of cases as most of the times atomicity is desired. For example, a simple increment statement such as x = x + 1; or x++ seems to be a single operation but is really a compound read-modify-write sequence of operations that must execute atomically.
What is volatile object in java
Вот четыре основных правила «happens-before» в Java: Правило захвата монитора (Monitor Lock Rule): Если поток A захватывает монитор объекта X, а затем выполняет операцию, а поток B должен захватить тот же монитор X, чтобы увидеть результаты изменений, выполненных потоком A. Другими словами, все операции, выполненные потоком A до освобождения монитора X, будут видны потоку B после захвата того же монитора X.
// Поток A synchronized (lock) < sharedVariable = 10; >// Поток B synchronized (lock) < int value = sharedVariable; // Гарантируется, что значение 10 будет видно потоку B >
Даже на 64-битных платформах, использование volatile с 64-битными переменными, такими как long и double, может быть недостаточным для обеспечения атомарности сложных операций. Например, если два потока пытаются одновременно выполнить операцию инкремента на volatile long переменной, может возникнуть состояние гонки, потому что инкремент состоит из нескольких операций чтения, модификации и записи. В таких случаях для обеспечения атомарности операций или синхронизации между потоками следует использовать средства синхронизации, такие как synchronized блоки или классы из пакета java.util.concurrent.atomic, которые предоставляют атомарные операции над переменными, включая 64-битные переменные.
volatile в априори не может создавать атомарное представление переменной, он лишь отменяет ее кэширование, что косвенно делает ее атомарной, но volatile != 100% атомарность
Правило 4 «Запись в volatile переменную happens-before чтение из той же переменной» Само собой это не происходит, мы сами это регулируем. Если мы запустим чтение/запись с разных потоков, какой поток и когда прочитает переменную c volatile зависит от самих потоков, и их конкуренции. Сдесь вывод будет разный, но в основном по первому потоку который был запущен.
public class Main < public volatile static String message = "No changes"; public static void main(String[] args) throws InterruptedException < new FreeThread().start(); new MyThread().start(); >public static class MyThread extends Thread < @Override public void run() < message = "Message was changed"; >> public static class FreeThread extends Thread < @Override public void run() < System.out.println(message); >> >
public class Solution < public static volatile int proposal = 0; public static void main(String[] args) throws InterruptedException < Thread mt1 = new Mt1(); Thread mt2 = new Mt2(); mt1.start(); mt2.start(); Thread.sleep(100); System.out.println(proposal + " " +Thread.currentThread().getName()); >public static class Mt1 extends Thread < @Override public void run() < proposal = 1; try < Thread.sleep(100); >catch (InterruptedException e) < throw new RuntimeException(e); >System.out.println(proposal + " " +Thread.currentThread().getName()); > > public static class Mt2 extends Thread < @Override public void run() < proposal = 2; try < Thread.sleep(100); >catch (InterruptedException e) < throw new RuntimeException(e); >System.out.println(proposal + " " +Thread.currentThread().getName()); > >
А в этом же коде без слипов выводит значения, соответствующие установленным в каждом треде, и никто не ждет никаких записей от других потоков. Выходит, что последний пункт вот вообще не работает с точки зрения синхронизации, потому что результат зависит от скорости выполнения тредов, и в зависимости от нее результаты будут совершенно разными. Это уже не говоря о планировщике. Да, можно починить при помощи join, но в таком случае получается поделка на тему синхронизации и не более. Бред какой-то..
What is volatile object in java
Learn Latest Tutorials
Preparation
Trending Technologies
B.Tech / MCA
Javatpoint Services
JavaTpoint offers too many high quality services. Mail us on h[email protected], to get more information about given services.
- Website Designing
- Website Development
- Java Development
- PHP Development
- WordPress
- Graphic Designing
- Logo
- Digital Marketing
- On Page and Off Page SEO
- PPC
- Content Development
- Corporate Training
- Classroom and Online Training
- Data Entry
Training For College Campus
JavaTpoint offers college campus training on Core Java, Advance Java, .Net, Android, Hadoop, PHP, Web Technology and Python. Please mail your requirement at [email protected].
Duration: 1 week to 2 week
Like/Subscribe us for latest updates or newsletter