Is the return statement atomic?
I pasted some code about Java concurrency:
public class ValueLatch <T> {
@GuardedBy("this") private T value = null;
private final CountDownLatch done = new CountDownLatch(1);
public boolean isSet() {
return (done.getCount() == 0);
}
public synchronized void setValue(T newValue) {
if (!isSet()) {
value = newValue;
done.countDown();
}
}
public T getValue() throws InterruptedException {
done.await();
synchronized (this) {
return value;
}
}
}
Why does return value; need to be synchronized???
Is the return statement not atomic??
java concurrency
add a comment |
I pasted some code about Java concurrency:
public class ValueLatch <T> {
@GuardedBy("this") private T value = null;
private final CountDownLatch done = new CountDownLatch(1);
public boolean isSet() {
return (done.getCount() == 0);
}
public synchronized void setValue(T newValue) {
if (!isSet()) {
value = newValue;
done.countDown();
}
}
public T getValue() throws InterruptedException {
done.await();
synchronized (this) {
return value;
}
}
}
Why does return value; need to be synchronized???
Is the return statement not atomic??
java concurrency
add a comment |
I pasted some code about Java concurrency:
public class ValueLatch <T> {
@GuardedBy("this") private T value = null;
private final CountDownLatch done = new CountDownLatch(1);
public boolean isSet() {
return (done.getCount() == 0);
}
public synchronized void setValue(T newValue) {
if (!isSet()) {
value = newValue;
done.countDown();
}
}
public T getValue() throws InterruptedException {
done.await();
synchronized (this) {
return value;
}
}
}
Why does return value; need to be synchronized???
Is the return statement not atomic??
java concurrency
I pasted some code about Java concurrency:
public class ValueLatch <T> {
@GuardedBy("this") private T value = null;
private final CountDownLatch done = new CountDownLatch(1);
public boolean isSet() {
return (done.getCount() == 0);
}
public synchronized void setValue(T newValue) {
if (!isSet()) {
value = newValue;
done.countDown();
}
}
public T getValue() throws InterruptedException {
done.await();
synchronized (this) {
return value;
}
}
}
Why does return value; need to be synchronized???
Is the return statement not atomic??
java concurrency
java concurrency
edited Nov 13 '18 at 20:40
Boann
36.8k1288121
36.8k1288121
asked Nov 13 '18 at 15:51
Li YunleiLi Yunlei
536
536
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.
The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.
I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.
the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?
– Li Yunlei
Nov 14 '18 at 15:03
Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.
– Matt Timmermans
Nov 14 '18 at 15:48
@MattTimmermans Why? When Thread A (callingsetValue) wrote tovaluebut did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value ofvalue. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?
– Hoopje
Nov 16 '18 at 11:50
Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of theCountDownLatchJavaDoc. Never mind :-)
– Hoopje
Nov 16 '18 at 11:56
add a comment |
The return statement needs to perform a read operation over value.
The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.
For that reason, the return should be synchronized.
6
Java generics use type erasure, so you do knowvalue's type -- it'sObject. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.
– Matt Timmermans
Nov 13 '18 at 18:46
Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7
– michid
Nov 13 '18 at 21:54
I was misinformed, thank you for correcting me. So it is useless to force synchronization here
– ricol070
Nov 14 '18 at 18:22
add a comment |
return value does not need to be synchronized:
- reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."
- each thread reading
valueis guaranteed to so see its latest value as according to the Java Memory Modelvalue = newValuehappens-beforedone.countDown(), which happens-beforedone.await(), which happens-beforereturn value. By transitivityvalue = newValuethus happens-beforereturn value.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284720%2fis-the-return-statement-atomic%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.
The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.
I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.
the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?
– Li Yunlei
Nov 14 '18 at 15:03
Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.
– Matt Timmermans
Nov 14 '18 at 15:48
@MattTimmermans Why? When Thread A (callingsetValue) wrote tovaluebut did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value ofvalue. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?
– Hoopje
Nov 16 '18 at 11:50
Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of theCountDownLatchJavaDoc. Never mind :-)
– Hoopje
Nov 16 '18 at 11:56
add a comment |
The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.
The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.
I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.
the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?
– Li Yunlei
Nov 14 '18 at 15:03
Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.
– Matt Timmermans
Nov 14 '18 at 15:48
@MattTimmermans Why? When Thread A (callingsetValue) wrote tovaluebut did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value ofvalue. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?
– Hoopje
Nov 16 '18 at 11:50
Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of theCountDownLatchJavaDoc. Never mind :-)
– Hoopje
Nov 16 '18 at 11:56
add a comment |
The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.
The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.
I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.
The return does not need to be synchronized. Since CountDownLatch.countDown() is not called until after the value is set for the last time, CountDownLatch.await() ensures that value is stable before it is read and returned.
The developer who wrote this was probably not quite sure of what he was doing (concurrency is difficult and dangerous) or, more likely, his use of the GuardedBy annotation on value caused his build system to emit a warning on the return, and some other developer synchronized it unnecessarily just to make the warning go away.
I say 'some other developer', because this class otherwise seems to be specifically designed to allow getValue() to proceed without locking once the value has been set.
edited Nov 13 '18 at 18:29
answered Nov 13 '18 at 18:22
Matt TimmermansMatt Timmermans
19k11532
19k11532
the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?
– Li Yunlei
Nov 14 '18 at 15:03
Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.
– Matt Timmermans
Nov 14 '18 at 15:48
@MattTimmermans Why? When Thread A (callingsetValue) wrote tovaluebut did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value ofvalue. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?
– Hoopje
Nov 16 '18 at 11:50
Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of theCountDownLatchJavaDoc. Never mind :-)
– Hoopje
Nov 16 '18 at 11:56
add a comment |
the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?
– Li Yunlei
Nov 14 '18 at 15:03
Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.
– Matt Timmermans
Nov 14 '18 at 15:48
@MattTimmermans Why? When Thread A (callingsetValue) wrote tovaluebut did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value ofvalue. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?
– Hoopje
Nov 16 '18 at 11:50
Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of theCountDownLatchJavaDoc. Never mind :-)
– Hoopje
Nov 16 '18 at 11:56
the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?
– Li Yunlei
Nov 14 '18 at 15:03
the example code above is from <<Java concurrency in practice>> ,the book is pretty old, so i want to ask does return statement is atomic in Java 1.5 or 1.6?
– Li Yunlei
Nov 14 '18 at 15:03
Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.
– Matt Timmermans
Nov 14 '18 at 15:48
Yes, the return statement is atomic in every way that that question makes sense, but the right question is whether or not it is guaranteed to see the right value... and it is. It's been this way since Java 1.5 when the java memory model was fixed.
– Matt Timmermans
Nov 14 '18 at 15:48
@MattTimmermans Why? When Thread A (calling
setValue) wrote to value but did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value of value. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?– Hoopje
Nov 16 '18 at 11:50
@MattTimmermans Why? When Thread A (calling
setValue) wrote to value but did not exit the synchronized function yet, Thread B (not in a synchronized block) may see the old value of value. Only when Thread A exits the synchronized function and Thread B enters a synchronized block on the same lock the Java Memory Model guarantees that the new value is visible to Thread B, or am I missing something?– Hoopje
Nov 16 '18 at 11:50
Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of the
CountDownLatch JavaDoc. Never mind :-)– Hoopje
Nov 16 '18 at 11:56
Ah, I see that what I was missing is the "Memory consistency effects" remark at the end of the
CountDownLatch JavaDoc. Never mind :-)– Hoopje
Nov 16 '18 at 11:56
add a comment |
The return statement needs to perform a read operation over value.
The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.
For that reason, the return should be synchronized.
6
Java generics use type erasure, so you do knowvalue's type -- it'sObject. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.
– Matt Timmermans
Nov 13 '18 at 18:46
Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7
– michid
Nov 13 '18 at 21:54
I was misinformed, thank you for correcting me. So it is useless to force synchronization here
– ricol070
Nov 14 '18 at 18:22
add a comment |
The return statement needs to perform a read operation over value.
The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.
For that reason, the return should be synchronized.
6
Java generics use type erasure, so you do knowvalue's type -- it'sObject. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.
– Matt Timmermans
Nov 13 '18 at 18:46
Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7
– michid
Nov 13 '18 at 21:54
I was misinformed, thank you for correcting me. So it is useless to force synchronization here
– ricol070
Nov 14 '18 at 18:22
add a comment |
The return statement needs to perform a read operation over value.
The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.
For that reason, the return should be synchronized.
The return statement needs to perform a read operation over value.
The read operation is atomic for most primitives, but you're dealing with a generic, meaning you won't know value's type.
For that reason, the return should be synchronized.
answered Nov 13 '18 at 17:27
ricol070ricol070
435211
435211
6
Java generics use type erasure, so you do knowvalue's type -- it'sObject. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.
– Matt Timmermans
Nov 13 '18 at 18:46
Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7
– michid
Nov 13 '18 at 21:54
I was misinformed, thank you for correcting me. So it is useless to force synchronization here
– ricol070
Nov 14 '18 at 18:22
add a comment |
6
Java generics use type erasure, so you do knowvalue's type -- it'sObject. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.
– Matt Timmermans
Nov 13 '18 at 18:46
Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7
– michid
Nov 13 '18 at 21:54
I was misinformed, thank you for correcting me. So it is useless to force synchronization here
– ricol070
Nov 14 '18 at 18:22
6
6
Java generics use type erasure, so you do know
value's type -- it's Object. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.– Matt Timmermans
Nov 13 '18 at 18:46
Java generics use type erasure, so you do know
value's type -- it's Object. Furthermore, reading any object-typed field is guaranteed to be atomic and will always produce an object-typed value, although memory barriers are required when transferring a value from one thread to another to ensure that the value read is up to date.– Matt Timmermans
Nov 13 '18 at 18:46
Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7
– michid
Nov 13 '18 at 21:54
Reading of references is always atomic. See docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7
– michid
Nov 13 '18 at 21:54
I was misinformed, thank you for correcting me. So it is useless to force synchronization here
– ricol070
Nov 14 '18 at 18:22
I was misinformed, thank you for correcting me. So it is useless to force synchronization here
– ricol070
Nov 14 '18 at 18:22
add a comment |
return value does not need to be synchronized:
- reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."
- each thread reading
valueis guaranteed to so see its latest value as according to the Java Memory Modelvalue = newValuehappens-beforedone.countDown(), which happens-beforedone.await(), which happens-beforereturn value. By transitivityvalue = newValuethus happens-beforereturn value.
add a comment |
return value does not need to be synchronized:
- reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."
- each thread reading
valueis guaranteed to so see its latest value as according to the Java Memory Modelvalue = newValuehappens-beforedone.countDown(), which happens-beforedone.await(), which happens-beforereturn value. By transitivityvalue = newValuethus happens-beforereturn value.
add a comment |
return value does not need to be synchronized:
- reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."
- each thread reading
valueis guaranteed to so see its latest value as according to the Java Memory Modelvalue = newValuehappens-beforedone.countDown(), which happens-beforedone.await(), which happens-beforereturn value. By transitivityvalue = newValuethus happens-beforereturn value.
return value does not need to be synchronized:
- reads of references is atomic according to the JLS: "Writes to and reads of references are always atomic, ..."
- each thread reading
valueis guaranteed to so see its latest value as according to the Java Memory Modelvalue = newValuehappens-beforedone.countDown(), which happens-beforedone.await(), which happens-beforereturn value. By transitivityvalue = newValuethus happens-beforereturn value.
answered Nov 13 '18 at 21:51
michidmichid
5,31121837
5,31121837
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284720%2fis-the-return-statement-atomic%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown