-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathjava-memory-model.html
More file actions
175 lines (162 loc) · 60.8 KB
/
java-memory-model.html
File metadata and controls
175 lines (162 loc) · 60.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Java - Java Memory Model</title>
<meta name="generator" content="VuePress 1.8.2">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="description" content="Motivation for the Memory Model, Happens-before relationships, Happens-before reasoning applied to some examples, How to avoid needing to understand the Memory Model">
<meta property="og:site_name" content="DevTut">
<meta property="og:title" content="Java - Java Memory Model">
<meta property="og:description" content="Motivation for the Memory Model, Happens-before relationships, Happens-before reasoning applied to some examples, How to avoid needing to understand the Memory Model">
<meta property="og:type" content="article">
<meta property="og:url" content="/java/java-memory-model.html">
<meta property="og:image" content="/logo.png">
<meta name="twitter:title" content="Java - Java Memory Model">
<meta name="twitter:description" content="Motivation for the Memory Model, Happens-before relationships, Happens-before reasoning applied to some examples, How to avoid needing to understand the Memory Model">
<meta name="twitter:url" content="/java/java-memory-model.html">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="/logo.png">
<meta name="theme-color" content="#ffffff">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="msapplication-TileImage" content="/mstile-150x150.png">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="google-site-verification" content="76_rKXgwMVIjd-axJC_1zPV9OS4mEjvtgjYOWVkAdnQ">
<link rel="preload" href="/assets/css/0.styles.60619e34.css" as="style"><link rel="preload" href="/assets/js/app.1779e102.js" as="script"><link rel="preload" href="/assets/js/3.2cfa8016.js" as="script"><link rel="preload" href="/assets/js/1592.8bab39ab.js" as="script">
<link rel="stylesheet" href="/assets/css/0.styles.60619e34.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">DevTut</span></a> <div class="links"><form id="search-form" role="search" class="algolia-search-wrapper search-box"><input id="algolia-search-input" class="search-query"></form> <nav class="nav-links can-hide"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Java</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/java/" aria-current="page" class="sidebar-link">Disclaimer</a></li><li><a href="/java/java-editions-versions-releases-and-distributions.html" class="sidebar-link">Java Editions, Versions, Releases and Distributions</a></li><li><a href="/java/installing-java-standard-edition.html" class="sidebar-link">Installing Java (Standard Edition)</a></li><li><a href="/java/getting-started-with-java-language.html" class="sidebar-link">Getting started with Java Language</a></li><li><a href="/java/type-conversion.html" class="sidebar-link">Type Conversion</a></li><li><a href="/java/getters-and-setters.html" class="sidebar-link">Getters and Setters</a></li><li><a href="/java/reference-data-types.html" class="sidebar-link">Reference Data Types</a></li><li><a href="/java/java-compiler-javac.html" class="sidebar-link">Java Compiler - 'javac'</a></li><li><a href="/java/documenting-java-code.html" class="sidebar-link">Documenting Java Code</a></li><li><a href="/java/command-line-argument-processing.html" class="sidebar-link">Command line Argument Processing</a></li><li><a href="/java/the-java-command-java-and-javaw.html" class="sidebar-link">The Java Command - 'java' and 'javaw'</a></li><li><a href="/java/literals.html" class="sidebar-link">Literals</a></li><li><a href="/java/primitive-data-types.html" class="sidebar-link">Primitive Data Types</a></li><li><a href="/java/strings.html" class="sidebar-link">Strings</a></li><li><a href="/java/stringbuffer.html" class="sidebar-link">StringBuffer</a></li><li><a href="/java/stringbuilder.html" class="sidebar-link">StringBuilder</a></li><li><a href="/java/string-tokenizer.html" class="sidebar-link">String Tokenizer</a></li><li><a href="/java/splitting-a-string-into-fixed-length-parts.html" class="sidebar-link">Splitting a string into fixed length parts</a></li><li><a href="/java/date-class.html" class="sidebar-link">Date Class</a></li><li><a href="/java/dates-and-time-java-time.html" class="sidebar-link">Dates and Time (java.time.*)</a></li><li><a href="/java/localtime.html" class="sidebar-link">LocalTime</a></li><li><a href="/java/bigdecimal.html" class="sidebar-link">BigDecimal</a></li><li><a href="/java/biginteger.html" class="sidebar-link">BigInteger</a></li><li><a href="/java/numberformat.html" class="sidebar-link">NumberFormat</a></li><li><a href="/java/bit-manipulation.html" class="sidebar-link">Bit Manipulation</a></li><li><a href="/java/arrays.html" class="sidebar-link">Arrays</a></li><li><a href="/java/collections.html" class="sidebar-link">Collections</a></li><li><a href="/java/lists.html" class="sidebar-link">Lists</a></li><li><a href="/java/sets.html" class="sidebar-link">Sets</a></li><li><a href="/java/list-vs-set.html" class="sidebar-link">List vs SET</a></li><li><a href="/java/maps.html" class="sidebar-link">Maps</a></li><li><a href="/java/linkedhashmap.html" class="sidebar-link">LinkedHashMap</a></li><li><a href="/java/weakhashmap.html" class="sidebar-link">WeakHashMap</a></li><li><a href="/java/sortedmap.html" class="sidebar-link">SortedMap</a></li><li><a href="/java/treemap-and-treeset.html" class="sidebar-link">TreeMap and TreeSet</a></li><li><a href="/java/queues-and-deques.html" class="sidebar-link">Queues and Deques</a></li><li><a href="/java/dequeue-interface.html" class="sidebar-link">Dequeue Interface</a></li><li><a href="/java/enums.html" class="sidebar-link">Enums</a></li><li><a href="/java/enum-map.html" class="sidebar-link">Enum Map</a></li><li><a href="/java/enumset-class.html" class="sidebar-link">EnumSet class</a></li><li><a href="/java/enum-starting-with-number.html" class="sidebar-link">Enum starting with number</a></li><li><a href="/java/hashtable.html" class="sidebar-link">Hashtable</a></li><li><a href="/java/operators.html" class="sidebar-link">Operators</a></li><li><a href="/java/constructors.html" class="sidebar-link">Constructors</a></li><li><a href="/java/object-class-methods-and-constructor.html" class="sidebar-link">Object Class Methods and Constructor</a></li><li><a href="/java/annotations.html" class="sidebar-link">Annotations</a></li><li><a href="/java/immutable-class.html" class="sidebar-link">Immutable Class</a></li><li><a href="/java/immutable-objects.html" class="sidebar-link">Immutable Objects</a></li><li><a href="/java/visibility-controlling-access-to-members-of-a-class.html" class="sidebar-link">Visibility (controlling access to members of a class)</a></li><li><a href="/java/generics.html" class="sidebar-link">Generics</a></li><li><a href="/java/classes-and-objects.html" class="sidebar-link">Classes and Objects</a></li><li><a href="/java/local-inner-class.html" class="sidebar-link">Local Inner Class</a></li><li><a href="/java/nested-and-inner-classes.html" class="sidebar-link">Nested and Inner Classes</a></li><li><a href="/java/the-java-util-objects-class.html" class="sidebar-link">The java.util.Objects Class</a></li><li><a href="/java/default-methods.html" class="sidebar-link">Default Methods</a></li><li><a href="/java/packages.html" class="sidebar-link">Packages</a></li><li><a href="/java/inheritance.html" class="sidebar-link">Inheritance</a></li><li><a href="/java/reference-types.html" class="sidebar-link">Reference Types</a></li><li><a href="/java/console-i-o.html" class="sidebar-link">Console I/O</a></li><li><a href="/java/streams.html" class="sidebar-link">Streams</a></li><li><a href="/java/inputstreams-and-outputstreams.html" class="sidebar-link">InputStreams and OutputStreams</a></li><li><a href="/java/readers-and-writers.html" class="sidebar-link">Readers and Writers</a></li><li><a href="/java/preferences.html" class="sidebar-link">Preferences</a></li><li><a href="/java/collection-factory-methods.html" class="sidebar-link">Collection Factory Methods</a></li><li><a href="/java/alternative-collections.html" class="sidebar-link">Alternative Collections</a></li><li><a href="/java/concurrent-collections.html" class="sidebar-link">Concurrent Collections</a></li><li><a href="/java/choosing-collections.html" class="sidebar-link">Choosing Collections</a></li><li><a href="/java/super-keyword.html" class="sidebar-link">super keyword</a></li><li><a href="/java/serialization.html" class="sidebar-link">Serialization</a></li><li><a href="/java/optional.html" class="sidebar-link">Optional</a></li><li><a href="/java/object-references.html" class="sidebar-link">Object References</a></li><li><a href="/java/exceptions-and-exception-handling.html" class="sidebar-link">Exceptions and exception handling</a></li><li><a href="/java/calendar-and-its-subclasses.html" class="sidebar-link">Calendar and its Subclasses</a></li><li><a href="/java/using-the-static-keyword.html" class="sidebar-link">Using the static keyword</a></li><li><a href="/java/properties-class.html" class="sidebar-link">Properties Class</a></li><li><a href="/java/lambda-expressions.html" class="sidebar-link">Lambda Expressions</a></li><li><a href="/java/basic-control-structures.html" class="sidebar-link">Basic Control Structures</a></li><li><a href="/java/bufferedwriter.html" class="sidebar-link">BufferedWriter</a></li><li><a href="/java/new-file-i-o.html" class="sidebar-link">New File I/O</a></li><li><a href="/java/file-i-o.html" class="sidebar-link">File I/O</a></li><li><a href="/java/scanner.html" class="sidebar-link">Scanner</a></li><li><a href="/java/interfaces.html" class="sidebar-link">Interfaces</a></li><li><a href="/java/regular-expressions.html" class="sidebar-link">Regular Expressions</a></li><li><a href="/java/comparable-and-comparator.html" class="sidebar-link">Comparable and Comparator</a></li><li><a href="/java/java-floating-point-operations.html" class="sidebar-link">Java Floating Point Operations</a></li><li><a href="/java/currency-and-money.html" class="sidebar-link">Currency and Money</a></li><li><a href="/java/object-cloning.html" class="sidebar-link">Object Cloning</a></li><li><a href="/java/recursion.html" class="sidebar-link">Recursion</a></li><li><a href="/java/converting-to-and-from-strings.html" class="sidebar-link">Converting to and from Strings</a></li><li><a href="/java/random-number-generation.html" class="sidebar-link">Random Number Generation</a></li><li><a href="/java/singletons.html" class="sidebar-link">Singletons</a></li><li><a href="/java/autoboxing.html" class="sidebar-link">Autoboxing</a></li><li><a href="/java/2d-graphics-in-java.html" class="sidebar-link">2D Graphics in Java</a></li><li><a href="/java/jaxb.html" class="sidebar-link">JAXB</a></li><li><a href="/java/class-java-reflection.html" class="sidebar-link">Class - Java Reflection</a></li><li><a href="/java/networking.html" class="sidebar-link">Networking</a></li><li><a href="/java/nio-networking.html" class="sidebar-link">NIO - Networking</a></li><li><a href="/java/httpurlconnection.html" class="sidebar-link">HttpURLConnection</a></li><li><a href="/java/jax-ws.html" class="sidebar-link">JAX-WS</a></li><li><a href="/java/nashorn-javascript-engine.html" class="sidebar-link">Nashorn JavaScript engine</a></li><li><a href="/java/java-native-interface.html" class="sidebar-link">Java Native Interface</a></li><li><a href="/java/functional-interfaces.html" class="sidebar-link">Functional Interfaces</a></li><li><a href="/java/fluent-interface.html" class="sidebar-link">Fluent Interface</a></li><li><a href="/java/remote-method-invocation-rmi.html" class="sidebar-link">Remote Method Invocation (RMI)</a></li><li><a href="/java/iterator-and-iterable.html" class="sidebar-link">Iterator and Iterable</a></li><li><a href="/java/reflection-api.html" class="sidebar-link">Reflection API</a></li><li><a href="/java/bytebuffer.html" class="sidebar-link">ByteBuffer</a></li><li><a href="/java/applets.html" class="sidebar-link">Applets</a></li><li><a href="/java/expressions.html" class="sidebar-link">Expressions</a></li><li><a href="/java/json-in-java.html" class="sidebar-link">JSON in Java</a></li><li><a href="/java/xml-parsing-using-the-jaxp-apis.html" class="sidebar-link">XML Parsing using the JAXP APIs</a></li><li><a href="/java/xml-xpath-evaluation.html" class="sidebar-link">XML XPath Evaluation</a></li><li><a href="/java/xom-xml-object-model.html" class="sidebar-link">XOM - XML Object Model</a></li><li><a href="/java/polymorphism.html" class="sidebar-link">Polymorphism</a></li><li><a href="/java/encapsulation.html" class="sidebar-link">Encapsulation</a></li><li><a href="/java/java-agents.html" class="sidebar-link">Java Agents</a></li><li><a href="/java/varargs-variable-argument.html" class="sidebar-link">Varargs (Variable Argument)</a></li><li><a href="/java/logging-java-util-logging.html" class="sidebar-link">Logging (java.util.logging)</a></li><li><a href="/java/log4j-log4j2.html" class="sidebar-link">log4j / log4j2</a></li><li><a href="/java/oracle-official-code-standard.html" class="sidebar-link">Oracle Official Code Standard</a></li><li><a href="/java/character-encoding.html" class="sidebar-link">Character encoding</a></li><li><a href="/java/apache-commons-lang.html" class="sidebar-link">Apache Commons Lang</a></li><li><a href="/java/localization-and-internationalization.html" class="sidebar-link">Localization and Internationalization</a></li><li><a href="/java/parallel-programming-with-fork-join-framework.html" class="sidebar-link">Parallel programming with Fork/Join framework</a></li><li><a href="/java/non-access-modifiers.html" class="sidebar-link">Non-Access Modifiers</a></li><li><a href="/java/process.html" class="sidebar-link">Process</a></li><li><a href="/java/java-native-access.html" class="sidebar-link">Java Native Access</a></li><li><a href="/java/modules.html" class="sidebar-link">Modules</a></li><li><a href="/java/concurrent-programming-threads.html" class="sidebar-link">Concurrent Programming (Threads)</a></li><li><a href="/java/executor-executorservice-and-thread-pools.html" class="sidebar-link">Executor, ExecutorService and Thread pools</a></li><li><a href="/java/threadlocal.html" class="sidebar-link">ThreadLocal</a></li><li><a href="/java/using-threadpoolexecutor-in-multithreaded-applications.html" class="sidebar-link">Using ThreadPoolExecutor in MultiThreaded applications.</a></li><li><a href="/java/common-java-pitfalls.html" class="sidebar-link">Common Java Pitfalls</a></li><li><a href="/java/java-pitfalls-exception-usage.html" class="sidebar-link">Java Pitfalls - Exception usage</a></li><li><a href="/java/java-pitfalls-language-syntax.html" class="sidebar-link">Java Pitfalls - Language syntax</a></li><li><a href="/java/java-pitfalls-threads-and-concurrency.html" class="sidebar-link">Java Pitfalls - Threads and Concurrency</a></li><li><a href="/java/java-pitfalls-nulls-and-nullpointerexception.html" class="sidebar-link">Java Pitfalls - Nulls and NullPointerException</a></li><li><a href="/java/java-pitfalls-performance-issues.html" class="sidebar-link">Java Pitfalls - Performance Issues</a></li><li><a href="/java/serviceloader.html" class="sidebar-link">ServiceLoader</a></li><li><a href="/java/classloaders.html" class="sidebar-link">Classloaders</a></li><li><a href="/java/creating-images-programmatically.html" class="sidebar-link">Creating Images Programmatically</a></li><li><a href="/java/atomic-types.html" class="sidebar-link">Atomic Types</a></li><li><a href="/java/rsa-encryption.html" class="sidebar-link">RSA Encryption</a></li><li><a href="/java/secure-objects.html" class="sidebar-link">Secure objects</a></li><li><a href="/java/security-cryptography.html" class="sidebar-link">Security & Cryptography</a></li><li><a href="/java/securitymanager.html" class="sidebar-link">SecurityManager</a></li><li><a href="/java/jndi.html" class="sidebar-link">JNDI</a></li><li><a href="/java/sun-misc-unsafe.html" class="sidebar-link">sun.misc.Unsafe</a></li><li><a href="/java/java-memory-model.html" aria-current="page" class="active sidebar-link">Java Memory Model</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/java/java-memory-model.html#motivation-for-the-memory-model" class="sidebar-link">Motivation for the Memory Model</a></li><li class="sidebar-sub-header"><a href="/java/java-memory-model.html#happens-before-relationships" class="sidebar-link">Happens-before relationships</a></li><li class="sidebar-sub-header"><a href="/java/java-memory-model.html#happens-before-reasoning-applied-to-some-examples" class="sidebar-link">Happens-before reasoning applied to some examples</a></li><li class="sidebar-sub-header"><a href="/java/java-memory-model.html#how-to-avoid-needing-to-understand-the-memory-model" class="sidebar-link">How to avoid needing to understand the Memory Model</a></li></ul></li><li><a href="/java/java-deployment.html" class="sidebar-link">Java deployment</a></li><li><a href="/java/java-plugin-system-implementations.html" class="sidebar-link">Java plugin system implementations</a></li><li><a href="/java/javabean.html" class="sidebar-link">JavaBean</a></li><li><a href="/java/java-se-7-features.html" class="sidebar-link">Java SE 7 Features</a></li><li><a href="/java/java-se-8-features.html" class="sidebar-link">Java SE 8 Features</a></li><li><a href="/java/dynamic-method-dispatch.html" class="sidebar-link">Dynamic Method Dispatch</a></li><li><a href="/java/generating-java-code.html" class="sidebar-link">Generating Java Code</a></li><li><a href="/java/jshell.html" class="sidebar-link">JShell</a></li><li><a href="/java/stack-walking-api.html" class="sidebar-link">Stack-Walking API</a></li><li><a href="/java/sockets.html" class="sidebar-link">Sockets</a></li><li><a href="/java/java-sockets.html" class="sidebar-link">Java Sockets</a></li><li><a href="/java/ftp-file-transfer-protocol.html" class="sidebar-link">FTP (File Transfer Protocol)</a></li><li><a href="/java/using-other-scripting-languages-in-java.html" class="sidebar-link">Using Other Scripting Languages in Java</a></li><li><a href="/java/c-comparison.html" class="sidebar-link">C++ Comparison</a></li><li><a href="/java/audio.html" class="sidebar-link">Audio</a></li><li><a href="/java/java-print-service.html" class="sidebar-link">Java Print Service</a></li><li><a href="/java/completablefuture.html" class="sidebar-link">CompletableFuture</a></li><li><a href="/java/runtime-commands.html" class="sidebar-link">Runtime Commands</a></li><li><a href="/java/unit-testing.html" class="sidebar-link">Unit Testing</a></li><li><a href="/java/asserting.html" class="sidebar-link">Asserting</a></li><li><a href="/java/multi-release-jar-files.html" class="sidebar-link">Multi-Release JAR Files</a></li><li><a href="/java/just-in-time-jit-compiler.html" class="sidebar-link">Just in Time (JIT) compiler</a></li><li><a href="/java/bytecode-modification.html" class="sidebar-link">Bytecode Modification</a></li><li><a href="/java/disassembling-and-decompiling.html" class="sidebar-link">Disassembling and Decompiling</a></li><li><a href="/java/jmx.html" class="sidebar-link">JMX</a></li><li><a href="/java/java-virtual-machine-jvm.html" class="sidebar-link">Java Virtual Machine (JVM)</a></li><li><a href="/java/xjc.html" class="sidebar-link">XJC</a></li><li><a href="/java/jvm-flags.html" class="sidebar-link">JVM Flags</a></li><li><a href="/java/jvm-tool-interface.html" class="sidebar-link">JVM Tool Interface</a></li><li><a href="/java/java-memory-management.html" class="sidebar-link">Java Memory Management</a></li><li><a href="/java/java-performance-tuning.html" class="sidebar-link">Java Performance Tuning</a></li><li><a href="/java/benchmarks.html" class="sidebar-link">Benchmarks</a></li><li><a href="/java/fileupload-to-aws.html" class="sidebar-link">FileUpload to AWS</a></li><li><a href="/java/appdynamics-and-tibco-businessworks-instrumentation-for-easy-integration.html" class="sidebar-link">AppDynamics and TIBCO BusinessWorks Instrumentation for Easy Integration</a></li><li><a href="/java/the-classpath.html" class="sidebar-link">The Classpath</a></li><li><a href="/java/resources-on-classpath.html" class="sidebar-link">Resources (on classpath)</a></li><li><a href="/java/contributors.html" class="sidebar-link">The Contributors</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="java-memory-model"><a href="#java-memory-model" class="header-anchor">#</a> Java Memory Model</h1> <h2 id="motivation-for-the-memory-model"><a href="#motivation-for-the-memory-model" class="header-anchor">#</a> Motivation for the Memory Model</h2> <p>Consider the following example:</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Example</span> <span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> c<span class="token punctuation">,</span> d<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">doIt</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
a <span class="token operator">=</span> b <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
c <span class="token operator">=</span> d <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>If this class is used is a single-threaded application, then the observable behavior will be exactly as you would expect. For instance:</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SingleThreaded</span> <span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token class-name">Example</span> eg <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Example</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>eg<span class="token punctuation">.</span>a <span class="token operator">+</span> <span class="token string">", "</span> <span class="token operator">+</span> eg<span class="token punctuation">.</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span>
eg<span class="token punctuation">.</span><span class="token function">doIt</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>eg<span class="token punctuation">.</span>a <span class="token operator">+</span> <span class="token string">", "</span> <span class="token operator">+</span> eg<span class="token punctuation">.</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>will output:</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span>
<span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span>
</code></pre></div><p><strong>As far as the "main" thread can tell</strong>, the statements in the <code>main()</code> method and the <code>doIt()</code> method will be executed in the order that they are written in the source code. This is a clear requirement of the Java Language Specification (JLS).</p> <p>Now consider the same class used in a multi-threaded application.</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MultiThreaded</span> <span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">final</span> <span class="token class-name">Example</span> eg <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Example</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Runnable</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
eg<span class="token punctuation">.</span><span class="token function">doIt</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>eg<span class="token punctuation">.</span>a <span class="token operator">+</span> <span class="token string">", "</span> <span class="token operator">+</span> eg<span class="token punctuation">.</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>What will this print?</p> <p>In fact, according to the JLS it is not possible to predict that this will print:</p> <ul><li>You will probably see a few lines of <code>0, 0</code> to start with.</li> <li>Then you probably see lines like <code>N, N</code> or <code>N, N + 1</code>.</li> <li>You might see lines like <code>N + 1, N</code>.</li> <li>In theory, you might even see that the <code>0, 0</code> lines continue forever<sup>1</sup>.</li></ul> <p><sup>1 - In practice the presence of the <code>println</code> statements is liable to cause some serendipitous synchronization and memory cache flushing. That is likely to hide some of the effects that would cause the above behavior.</sup></p> <p>So how can we explain these?</p> <h3 id="reordering-of-assignments"><a href="#reordering-of-assignments" class="header-anchor">#</a> Reordering of assignments</h3> <p>One possible explanation for unexpected results is that the JIT compiler has changed the order of the assignments in the <code>doIt()</code> method. The JLS requires that statements <strong>appear to</strong> execute in order <strong>from the perspective of the current</strong> thread. In this case, nothing in the code of the <code>doIt()</code> method can observe the effect of a (hypothetical) reordering of those two statement. This means that the JIT compiler would be permitted to do that.</p> <p>Why would it do that?</p> <p>On typical modern hardware, machine instructions are executed using a instruction pipeline which allows a sequence of instructions to be in different stages. Some phases of instruction execution take longer than others, and memory operations tend to take a longer time. A smart compiler can optimize the instruction throughput of the pipeline by ordering the instructions to maximize the amount of overlap. This may lead to executing parts of statements out of order. The JLS permits this provided that not affect the result of the computation <strong>from the perspective of the current thread</strong>.</p> <h3 id="effects-of-memory-caches"><a href="#effects-of-memory-caches" class="header-anchor">#</a> Effects of memory caches</h3> <p>A second possible explanation is effect of memory caching. In a classical computer architecture, each processor has a small set of registers, and a larger amount of memory. Access to registers is much faster than access to main memory. In modern architectures, there are memory caches that are slower than registers, but faster than main memory.</p> <p>A compiler will exploit this by trying to keep copies of variables in registers, or in the memory caches. If a variable does not <strong>need</strong> to be flushed to main memory, or does not <strong>need</strong> to be read from memory, there are significant performance benefits in not doing this. In cases where the JLS does not require memory operations to be visible to another thread, the Java JIT compiler is likely to not add the "read barrier" and "write barrier" instructions that will force main memory reads and writes. Once again, the performance benefits of doing this are significant.</p> <h3 id="proper-synchronization"><a href="#proper-synchronization" class="header-anchor">#</a> Proper synchronization</h3> <p>So far, we have seen that the JLS allows the JIT compiler to generate code that makes single-threaded code faster by reordering or avoiding memory operations. But what happens when other threads can observe the state of the (shared) variables in main memory?</p> <p>The answer is, that the other threads are liable to observe variable states which would appear to be impossible ... based on the code order of the Java statements. The solution to this is to use appropriate synchronization. The three main approaches are:</p> <ul><li>Using primitive mutexes and the <code>synchronized</code> constructs.</li> <li>Using <code>volatile</code> variables.</li> <li>Using higher level concurrency support; e.g. classes in the <code>java.util.concurrent</code> packages.</li></ul> <p>But even with this, it is important to understand where synchronization is needed, and what effects that you can rely on. This is where the Java Memory Model comes in.</p> <h3 id="the-memory-model"><a href="#the-memory-model" class="header-anchor">#</a> The Memory Model</h3> <p>The Java Memory Model is the section of the JLS that specifies the conditions under which one thread is guaranteed to see the effects of memory writes made by another thread. The Memory Model is specified with a fair degree of <strong>formal rigor</strong>, and (as a result) requires detailed and careful reading to understand. But the basic principle is that certain constructs create a "happens-before" relation between write of a variable by one thread, and a subsequent read of the same variable by another thread. If the "happens before" relation exists, the JIT compiler is <strong>obliged</strong> to generate code that will ensure that the read operation sees the value written by the write.</p> <p>Armed with this, it is possible to reason about memory coherency in a Java program, and decide whether this will be predictable and consistent for <strong>all</strong> execution platforms.</p> <h2 id="happens-before-relationships"><a href="#happens-before-relationships" class="header-anchor">#</a> Happens-before relationships</h2> <p>(The following is a simplified version of what the Java Language Specification says. For a deeper understanding, you need to read the specification itself.)</p> <p>Happens-before relationships are the part of the Memory Model that allow us to understand and reason about memory visibility. As the JLS says (<a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.5" target="_blank" rel="noopener noreferrer">JLS 17.4.5<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>):</p> <blockquote></blockquote> <p>"Two <strong>actions</strong> can be ordered by a <strong>happens-before</strong> relationship. If one action <strong>happens-before</strong> another, then the first is visible to and ordered before the second."</p> <p>What does this mean?</p> <h3 id="actions"><a href="#actions" class="header-anchor">#</a> Actions</h3> <p>The actions that the above quote refers to are specified in <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.2" target="_blank" rel="noopener noreferrer">JLS 17.4.2<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>. There are 5 kinds of action listed defined by the spec:</p> <li>
Read: Reading a non-volatile variable.
</li> <li>
Write: Writing a non-volatile variable.
</li> <li>
Synchronization actions:
<ul><li>
Volatile read: Reading a volatile variable.
</li> <li>
Volatile write: Writing a volatile variable.
</li> <li>
Lock. Locking a monitor
</li> <li>
Unlock. Unlocking a monitor.
</li> <li>
The (synthetic) first and last actions of a thread.
</li> <li>
Actions that start a thread or detect that a thread has terminated.
</li> <p>External Actions. An action that has a result that depends on the environment in which the program.</p> <p>Thread divergence actions. These model the behavior of certain kinds of infinite loop.</p> <h3 id="program-order-and-synchronization-order"><a href="#program-order-and-synchronization-order" class="header-anchor">#</a> Program Order and Synchronization Order</h3> <p>These two orderings ( <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.3" target="_blank" rel="noopener noreferrer">JLS 17.4.3<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> and <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.4" target="_blank" rel="noopener noreferrer">JLS 17.4.4<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> ) govern the execution of statements in a Java</p> <p>Program order describes the order of statement execution within a single thread.</p> <p>Synchronization order describes the order of statement execution for two statements connected by a synchronization:</p> <li>
An unlock action on monitor **synchronizes-with** all subsequent lock actions on that monitor.
</li> <li>
A write to a volatile variable **synchronizes-with** all subsequent reads of the same variable by any thread.
</li> <li>
An action that starts a thread (i.e. the call to `Thread.start()`) **synchronizes-with** the first action in the thread it starts (i.e. the call to the thread's `run()` method).
</li> <li>
The default initialization of fields **synchronizes-with** the first action in every thread. (See the JLS for an explanation of this.)
</li> <li>
The final action in a thread **synchronizes-with** any action in another thread that detects the termination; e.g. the return of a `join()` call or `isTerminated()` call that returns `true`.
</li> <li>
If one thread interrupts another thread, the interrupt call in the first thread **synchronizes-with** the point where another thread detects that the thread was interrupted.
</li> <h3 id="happens-before-order"><a href="#happens-before-order" class="header-anchor">#</a> Happens-before Order</h3> <p>This ordering ( <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.5" target="_blank" rel="noopener noreferrer">JLS 17.4.5<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> ) is what determines whether a memory write is guaranteed to be visible to a subsequent memory read.</p> <p>More specifically, a read of a variable <code>v</code> is guaranteed to observe a write to <code>v</code> if and only if <code>write(v)</code> <strong>happens-before</strong> <code>read(v)</code> AND there is no intervening write to <code>v</code>. If there are intervening writes, then the <code>read(v)</code> may see the results of them rather than the earlier one.</p> <p>The rules that define the <strong>happens-before</strong> ordering are as follows:</p> <li>
**Happens-Before Rule #1** - If x and y are actions of the same thread and x comes before y in **program order**, then x **happens-before** y.
</li> <li>
**Happens-Before Rule #2** - There is a happens-before edge from the end of a constructor of an object to the start of a finalizer for that object.
</li> <li>
**Happens-Before Rule #3** - If an action x **synchronizes-with** a subsequent action y, then x **happens-before** y.
</li> <li>
**Happens-Before Rule #4** - If x **happens-before** y and y **happens-before** z then x **happens-before** z.
</li> <p>In addition, various classes in the Java standard libraries are specified as defining <strong>happens-before</strong> relationships. You can interpret this as meaning that it happens <strong>somehow</strong>, without needing to know exactly how the guarantee is going to be met.</p> <h2 id="happens-before-reasoning-applied-to-some-examples"><a href="#happens-before-reasoning-applied-to-some-examples" class="header-anchor">#</a> Happens-before reasoning applied to some examples</h2> <p>We will present some examples to show how to apply <strong>happens-before</strong> reasoning to check that writes are visible to subsequent reads.</p> <h3 id="single-threaded-code"><a href="#single-threaded-code" class="header-anchor">#</a> Single-threaded code</h3> <p>As you would expect, writes are always visible to subsequent reads in a single-threaded program.</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SingleThreadExample</span> <span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> a<span class="token punctuation">,</span> b<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// write(a)</span>
b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// write(b)</span>
<span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token comment">// read(a) followed by read(b)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>By Happens-Before Rule #1:</p> <ol><li>The <code>write(a)</code> action <strong>happens-before</strong> the <code>write(b)</code> action.</li> <li>The <code>write(b)</code> action <strong>happens-before</strong> the <code>read(a)</code> action.</li> <li>The <code>read(a)</code> action <strong>happens-before</strong> the <code>read(a)</code> action.</li></ol> <p>By Happens-Before Rule #4:</p> <ol><li><code>write(a)</code> <strong>happens-before</strong> <code>write(b)</code> AND <code>write(b)</code> <strong>happens-before</strong> <code>read(a)</code> IMPLIES <code>write(a)</code> <strong>happens-before</strong> <code>read(a)</code>.</li> <li><code>write(b)</code> <strong>happens-before</strong> <code>read(a)</code> AND <code>read(a)</code> <strong>happens-before</strong> <code>read(b)</code> IMPLIES <code>write(b)</code> <strong>happens-before</strong> <code>read(b)</code>.</li></ol> <p>Summing up:</p> <ol><li>The <code>write(a)</code> <strong>happens-before</strong> <code>read(a)</code> relation means that the <code>a + b</code> statement is guaranteed to see the correct value of <code>a</code>.</li> <li>The <code>write(b)</code> <strong>happens-before</strong> <code>read(b)</code> relation means that the <code>a + b</code> statement is guaranteed to see the correct value of <code>b</code>.</li></ol> <h3 id="behavior-of-volatile-in-an-example-with-2-threads"><a href="#behavior-of-volatile-in-an-example-with-2-threads" class="header-anchor">#</a> Behavior of 'volatile' in an example with 2 threads</h3> <p>We will use the following example code to explore some implications of the Memory Model for `volatile.</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">VolatileExample</span> <span class="token punctuation">{</span>
<span class="token keyword">private</span> <span class="token keyword">volatile</span> <span class="token keyword">int</span> a<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">int</span> b<span class="token punctuation">;</span> <span class="token comment">// NOT volatile</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">update</span><span class="token punctuation">(</span><span class="token keyword">int</span> first<span class="token punctuation">,</span> <span class="token keyword">int</span> second<span class="token punctuation">)</span> <span class="token punctuation">{</span>
b <span class="token operator">=</span> first<span class="token punctuation">;</span> <span class="token comment">// write(b)</span>
a <span class="token operator">=</span> second<span class="token punctuation">;</span> <span class="token comment">// write-volatile(a)</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">observe</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token comment">// read-volatile(a) followed by read(b)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>First, consider the following sequence of statements involving 2 threads:</p> <ol><li>A single instance of <code>VolatileExample</code> is created; call it <code>ve</code>,</li> <li><code>ve.update(1, 2)</code> is called in one thread, and</li> <li><code>ve.observe()</code> is called in another thread.</li></ol> <p>By Happens-Before Rule #1:</p> <ol><li>The <code>write(a)</code> action <strong>happens-before</strong> the <code>volatile-write(a)</code> action.</li> <li>The <code>volatile-read(a)</code> action <strong>happens-before</strong> the <code>read(b)</code> action.</li></ol> <p>By Happens-Before Rule #2:</p> <ol><li>The <code>volatile-write(a)</code> action in the first thread <strong>happens-before</strong> the <code>volatile-read(a)</code> action in the second thread.</li></ol> <p>By Happens-Before Rule #4:</p> <ol><li>The <code>write(b)</code> action in the first thread <strong>happens-before</strong> the <code>read(b)</code> action in the second thread.</li></ol> <p>In other words, for this particular sequence, we are guaranteed that the 2nd thread will see the update to the non-volatile variable <code>b</code> made by the first thread. However, it is should also be clear that if the assignments in the <code>update</code> method were the other way around, or the <code>observe()</code> method read the variable <code>b</code> before <code>a</code>, then the <strong>happens-before</strong> chain would be broken. The chain would also be broken if <code>volatile-read(a)</code> in the second thread was not subsequent to the <code>volatile-write(a)</code> in the first thread.</p> <p>When the chain is broken, there is no <strong>guarantee</strong> that <code>observe()</code> will see the correct value of <code>b</code>.</p> <h3 id="volatile-with-three-threads"><a href="#volatile-with-three-threads" class="header-anchor">#</a> Volatile with three threads</h3> <p>Suppose we to add a third thread into the previous example:</p> <ol><li>A single instance of <code>VolatileExample</code> is created; call it <code>ve</code>,
</li><li>Two threads call <code>update</code>:
<ul></ul></li> <li><code>ve.update(1, 2)</code> is called in one thread,</li> <li><code>ve.update(3, 4)</code> is called in the second thread,
</li></ol></ul></li> <li><code>ve.observe()</code> is subsequently called in a third thread.</li> <p>To analyse this completely, we need to consider all of the possible interleavings of the statements in thread one and thread two. Instead, we will consider just two of them.</p> <p>Scenario #1 - suppose that <code>update(1, 2)</code> precedes <code>update(3,4)</code> we get this sequence:</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token function">write</span><span class="token punctuation">(</span>b<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> write<span class="token operator">-</span><span class="token keyword">volatile</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment">// first thread</span>
<span class="token function">write</span><span class="token punctuation">(</span>b<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> write<span class="token operator">-</span><span class="token keyword">volatile</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token comment">// second thread</span>
read<span class="token operator">-</span><span class="token keyword">volatile</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">read</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span> <span class="token comment">// third thread</span>
</code></pre></div><p>In this case, it is easy to see that there is an unbroken <strong>happens-before</strong> chain from <code>write(b, 3)</code> to <code>read(b)</code>. Furthermore there is no intervening write to <code>b</code>. So, for this scenario, the third thread is guaranteed to see <code>b</code> as having value <code>3</code>.</p> <p>Scenario #2 - suppose that <code>update(1, 2)</code> and <code>update(3,4)</code> overlap and the ations are interleaved as follows:</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token function">write</span><span class="token punctuation">(</span>b<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment">// second thread</span>
<span class="token function">write</span><span class="token punctuation">(</span>b<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment">// first thread</span>
write<span class="token operator">-</span><span class="token keyword">volatile</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment">// first thread</span>
write<span class="token operator">-</span><span class="token keyword">volatile</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token comment">// second thread</span>
read<span class="token operator">-</span><span class="token keyword">volatile</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">read</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span> <span class="token comment">// third thread</span>
</code></pre></div><p>Now, while there is a <strong>happens-before</strong> chain from <code>write(b, 3)</code> to <code>read(b)</code>, there is an intervening <code>write(b, 1)</code> action performed by the other thread. This means we cannot be certain which value <code>read(b)</code> will see.</p> <p>(Aside: This demonstrates that we cannot rely on <code>volatile</code> for ensuring visibility of non-volatile variables, except in very limited situations.)</p> <h2 id="how-to-avoid-needing-to-understand-the-memory-model"><a href="#how-to-avoid-needing-to-understand-the-memory-model" class="header-anchor">#</a> How to avoid needing to understand the Memory Model</h2> <p>The Memory Model is difficult to understand, and difficult to apply. It is useful if you need to reason about the correctness of multi-threaded code, but you do not want to have to do this reasoning for every multi-threaded application that you write.</p> <p>If you adopt the following principals when writing concurrent code in Java, you can <strong>largely</strong> avoid the need to resort to <strong>happens-before</strong> reasoning.</p> <li>
Use immutable data structures where possible. A properly implemented immutable class will be thread-safe, and will not introduce thread-safety issues when you use it with other classes.
</li> <li>
Understand and avoid "unsafe publication".
</li> <li>
Use primitive mutexes or `Lock` objects to synchronize access to state in mutable objects that need to be thread-safe<sup>1</sup>.
</li> <li>
Use `Executor` / `ExecutorService` or the fork join framework rather than attempting to create manage threads directly.
</li> <li>
Use the `java.util.concurrent classes that provide advanced locks, semaphores, latches and barriers, instead of using wait/notify/notifyAll directly.
</li> <li>
Use the `java.util.concurrent` versions of maps, sets, lists, queues and deques rather than external synchonization of non-concurrent collections.
</li> <p>The general principle is to try to use Java's built-in concurrency libraries rather than "rolling your own" concurrency. You can rely on them working, if you use them properly.</p> <p><sup>1 - Not all objects need to be thread safe. For example, if an object or objects is <strong>thread-confined</strong> (i.e. it is only accessible to one thread), then its thread-safety is not relevant.</sup></p> <h4 id="remarks"><a href="#remarks" class="header-anchor">#</a> Remarks</h4> <p>The Java Memory Model is the section of the JLS that specifies the conditions under which one thread is guaranteed to see the effects of memory writes made by another thread. The relevant section in recent editions is "JLS 17.4 Memory Model" (in <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4" target="_blank" rel="noopener noreferrer">Java 8<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, <a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4" target="_blank" rel="noopener noreferrer">Java 7<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, <a href="https://docs.oracle.com/javase/specs/jls/se6/html/memory.html#17.4" target="_blank" rel="noopener noreferrer">Java 6<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>)</p> <p>There was a major overhaul of the Java Memory Model in Java 5 which (among other things) changed the way that <code>volatile</code> worked. Since then, the memory model been essentially unchanged.</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/devtut/generate/edit/master/docs/java/java-memory-model.md" target="_blank" rel="noopener noreferrer">Edit this page on GitHub</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
←
<a href="/java/sun-misc-unsafe.html" class="prev">
sun.misc.Unsafe
</a></span> <span class="next"><a href="/java/java-deployment.html">
Java deployment
</a>
→
</span></p></div> </main></div><div class="global-ui"><!----></div></div>
<script src="/assets/js/app.1779e102.js" defer></script><script src="/assets/js/3.2cfa8016.js" defer></script><script src="/assets/js/1592.8bab39ab.js" defer></script>
</body>
</html>