What are the possible ways to make code thread-safe without using the synchronized
keyword?
-
2why close ? Its a good succinct question – NimChimpsky Apr 26 '12 at 09:55
-
@NimChimpsky I don't know either, the question seems perfectly valid to me. It is definitely answerable, and the answers are not something subjective. – Malcolm Apr 26 '12 at 10:00
-
@NimChimpsky "Too broad" I presume. – OrangeDog Aug 03 '18 at 11:31
-
To add to discussion I just posted a lengthy epilogue here [Thread synchronization without locks](https://stackoverflow.com/a/68127763) – mindiga Jun 25 '21 at 10:19
-
I just posted the answer here. [Synchronization without locks](https://stackoverflow.com/a/68127763) – mindiga Jun 25 '21 at 10:20
7 Answers
Actually, lots of ways:
- No need for synchronization at all if you don't have mutable state.
- No need for synchronization if the mutable state is confined to a single thread. This can be done by using local variables or
java.lang.ThreadLocal
. - You can also use built-in synchronizers.
java.util.concurrent.locks.ReentrantLock
has the same functionality as the lock you access when usingsynchronized
blocks and methods, and it is even more powerful.

- 41,014
- 11
- 68
- 91
-
1I prefer (2), but I'm not sure if its' possible to implement message-passing without using the 'synchronized' keyword. Can I make a producer-consumer queue without 'synchronized'? – Martin James Apr 26 '12 at 10:07
-
1@MartinJames Any of the Concurrent classes like Queues and Exchangers can be used without synchronization. (They use Lock instead) The Disrupter supports messaging without locks or synchronization. (I have a library which does this as well) – Peter Lawrey Apr 26 '12 at 11:27
-
@PeterLawrey - so, thread-safe code without the 'synchronized' keyword is certainly possible and, in fact practical. Now, all that remains is to get developers to stop using Thread.join() and we're done :) – Martin James Apr 26 '12 at 11:43
-
@MartinJames It is better to say that thread-safe code is possible without *locking*. Sometimes you can avoid using locking completely (intrinsic locks or not, doesn't matter), and then everything becomes much easier. However, if you get to locking, it is better to use `synchronized` than extrinsic locks if you don't need advanced features. The notaion of intrinsic locks is concise, and the code doesn't need to contain try-finally blocks (therefore much safer). – Malcolm Apr 26 '12 at 12:29
Only have variables/references local to methods. Or ensure that any instance variables are immutable.

- 46,453
- 60
- 198
- 311
You can make your code thread-safe by making all the data immutable, if there is no mutability, everything is thread-safe.
Secondly, you may want to have a look at java concurrent API which has provision for providing read / write locks which perform better in case there are lots of readers and a few writers. Pure synchronized keyword will block two readers also.

- 6,285
- 2
- 24
- 30
////////////FIRST METHOD USING SINGLE boolean//////////////
public class ThreadTest implements Runnable {
ThreadTest() {
Log.i("Ayaz", "Constructor..");
}
private boolean lockBoolean = false;
public void run() {
Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
while (lockBoolean) {
// infinite loop for other thread if one is accessing
}
lockBoolean = true;
synchronizedMethod();
}
/**
* This method is synchronized without using synchronized keyword
*/
public void synchronizedMethod() {
Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
System.out.println("Exp");
}
Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
lockBoolean = false;
}
} //end of ThreadTest class
//For testing use below line in main method or in Activity
ThreadTest threadTest = new ThreadTest();
Thread threadA = new Thread(threadTest, "A thead");
Thread threadB = new Thread(threadTest, "B thead");
threadA.start();
threadB.start();
///////////SECOND METHOD USING TWO boolean/////////////////
public class ThreadTest implements Runnable {
ThreadTest() {
Log.i("Ayaz", "Constructor..");
}
private boolean isAnyThreadInUse = false;
private boolean lockBoolean = false;
public void run() {
Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
while (!lockBoolean)
if (!isAnyThreadInUse) {
isAnyThreadInUse = true;
synchronizedMethod();
lockBoolean = true;
}
}
/**
* This method is synchronized without using synchronized keyword
*/
public void synchronizedMethod() {
Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
System.out.println("Exp");
}
Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
isAnyThreadInUse = false;
}
} // end of ThreadTest class
//For testing use below line in main method or in Activity
ThreadTest threadTest = new ThreadTest();
Thread t1 = new Thread(threadTest, "a thead");
Thread t2 = new Thread(threadTest, "b thead");
t1.start();
t2.start();

- 151
- 1
- 5
To maintain predictability you must either ensure all access to mutable data is made sequentially or handle the issues caused by parallel access.
The most gross protection uses the synchronized
keyword. Beyond that there are at least two layers of possibility, each with their benefits.
Locks/Semaphores
These can be very effective. For example, if you have a structure that is read by many threads but only updated by one you may find a ReadWriteLock
useful.
Locks can be much more efficient if you choose your lock to match the algorithm.
Atomics
Use of AtomicReference
for example can often provide completely lock free functionality. This can usually provide huge benefits.
The reasoning behind atomics is to allow them to fail but to tell you they failed in a way you can handle it.
For example, if you want to change a value you can read it and then write its new value so long as it is still the old value. This is called a "compare and set" or cas
and can usually be implemented in hardware and so is extremely efficient. All you then need is something like:
long old = atomic.get();
while ( !atomic.cas(old, old+1) ) {
// The value changed between my get and the cas. Get it again.
old = atomic.get();
}
Note, however, that predictability is not always the requirement.

- 64,482
- 16
- 119
- 213
Well there are many ways you can achieve this, but each contains many flavors. Java 8 also ships with new concurrency features.
Some ways you could make sure thread safety are:
Semaphores
Locks-Reentrantlock,ReadWriteLock,StampedLock
(Java 8)

- 31
- 6
Why do u need to do it?
Using only local variable/references will not solve most of the complex business needs. Also, if instance variable are immutable, their references can still be changed by other threads.
One option is use something like a SingleThreadModel, but it is highly discouraged and deprecated.
u can also look at concurrent api as suggested above by Kal

- 8,474
- 2
- 26
- 34
-
"if instance variable are immutable, their references can still be changed" no they can't – NimChimpsky Apr 26 '12 at 10:03
-
can u explain that. How i see it is if i have a instanace variable String s ="xyz", My thread1 can change the reference of it to s="abc"; and thread2 will now get s="abc" – Kshitij Apr 26 '12 at 10:08
-
s is a reference, it has changed, its not immutable you would need "final string s" – NimChimpsky Apr 26 '12 at 10:11
-
http://stackoverflow.com/questions/1568722/on-the-thread-safety-of-instance-variable-initialization – NimChimpsky Apr 26 '12 at 10:17
-
"final String s" will not solve the purpose here as it will just act as a constant. – Kshitij Apr 26 '12 at 10:18
-
1with string s your s reference is not immutable it can reference a different string, just by doing s = "yourarewrong". You say immutable instance variables are not thread safe, and then give an example of a mutable instance variable. – NimChimpsky Apr 26 '12 at 10:21
-
that's what i am asking you. "show me an example of immutable instance variable". – Kshitij Apr 26 '12 at 10:26
-
as per my understanding, there's nothing like immutable instance variable – Kshitij Apr 26 '12 at 10:27
-
-
let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/10541/discussion-between-kshitij-and-nimchimpsky) – Kshitij Apr 26 '12 at 10:31