java - How to write a simple thread-safe class using a volatile variable? -
i want write simple thread-safe class used set or integer value.
the easiest way use synchronized keyword:
public class myintegerholder { private integer value; synchronized public integer getvalue() { return value; } synchronized public void setvalue(integer value) { this.value = value; } } i try using volatile:
public class myintegerholder { private volatile integer value; public integer getvalue() { return value; } public void setvalue(integer value) { this.value = value; } } is class volatile keyword thread-safe?
consider following sequence of events:
- thread sets value 5.
- thread b sets value 7.
- thread c reads value.
it follows java language specification that
- "1" happens-before "3"
- "2" happens-before "3"
but don't see how follow specification "1" happens-before "2" suspect "1" doesn't happen-before "2".
i suspect thread c may read 7 or 5. think class volatile keyword not thread-safe , following sequence possible:
- thread sets value 5.
- thread b sets value 7.
- thread c reads 7.
- thread d reads 5.
- thread c reads 7.
- thread d reads 5.
- ...
am correct in assuming myintegerholder volatile not thread-safe?
is possible make thread-safe integer holder using atomicinteger:
public class myintegerholder { private atomicinteger atomicinteger = new atomicinteger(); public integer getvalue() { return atomicinteger.get(); } public void setvalue(integer value) { atomicinteger.set(value); } } ?
here fragment of java concurrency in practice book:
"reads , writes of atomic variables have same memory semantics volatile variables."
what best (preferably non-blocking) way of writing thread-safe myintegerholder?
if know answer, know why think correct. follow specification? if so, how?
the keyword synchronized saying if thread , thread b want access integer, cannot simultaneously. telling b wait until i'm done it.
on other hand, volatile makes threads more "friendly". start talking each other , working perform tasks. when b tries access, inform b of has done until moment. b aware of changes , can continue job left of.
in java, have atomic reason, under covers use volatile keyword, doing pretty same thing, save time , effort.
the thing looking atomicinteger, right this. operation trying perform best choice.
there 2 main uses of `atomicinteger`: * atomic counter (incrementandget(), etc) can used many threads concurrently * primitive supports compare-and-swap instruction (compareandset()) implement non-blocking algorithms. to answer question on general note
it depends on need. i'm not saying synchronized wrong , volatile good, otherwise nice java people have removed synchronized long time ago. there no absolute answer, there lot of specific cases , usage scenarios.
a few of bookmarks:
update
from java concurrency specification available here:
package java.util.concurrent.atomic
a small toolkit of classes support lock-free thread-safe programming on single variables.
instances of classes `atomicboolean`, `atomicinteger`, `atomiclong`, , `atomicreference` each provide access , updates single variable of corresponding type. each class provides appropriate utility methods type. example, classes `atomiclong` , atomicinteger provide atomic increment methods. memory effects accesses , updates of atomics follow rules volatiles: has memory effects of reading volatile variable. set has memory effects of writing (assigning) volatile variable. also here
the java programming language volatile keyword:
(in versions of java) there global ordering on reads , writes volatile variable. implies every thread accessing volatile field will read current value before continuing, instead of (potentially) using cached value. (however, there no guarantee relative ordering of volatile reads , writes regular reads , writes, meaning it's not useful threading construct.)
Comments
Post a Comment