Reputation:
I have 2 threads in my program as follows:
class SendThread implements Runnable {
public void run(){
Thread.sleep(1000);
while (true){
if (CONNECTION_ESTABLISHED){
// code here
}
}
}
}
class ReceiveThread implements Runnable {
public void run(){
while (true){
// code here
CONNECTION_ESTABLISHED = true;
}
}
}
I have defined CONNECTION_ESTABLISHED
as a static Boolean
.
In the second thread, the Boolean
CONNECTION_ESTABLISHED
is set to true
at a certain point. If I don't use Thread.sleep(1000)
in the 1st thread, after CONNECTION_ESTABLISHED
is set to true
in the 2nd thread I don't enter the relevant if
statement in the 1st thread.
Is there another way around this? Because my 1st thread will often be dependent on variable changes in the second thread.
Upvotes: 2
Views: 177
Reputation: 68715
You are facing teh challenge because you are changing the static variable CONNECTION_ESTABLISHED in a non-synchronized way and you are not using the wait notify mechanism for thread communication. Using wait notify should help you. Create an object to be used for wait-notify and use the code as below
class SendThread implements Runnable {
public void run(){
Thread.sleep(1000);
while (true){
synchronized(object) {
object.wait();
if (CONNECTION_ESTABLISHED){
// code here
}
}
}
}
}
class ReceiveThread implements Runnable {
public void run(){
while (true){
synchronized(object) {
// code here
CONNECTION_ESTABLISHED = true;
object.notify();
}
}
}
}
I have not tested the code, i have just tried to put the concept so make changes as required.
Upvotes: 0
Reputation: 23229
In this particular example you can mark the CONNECTION_ESTABLISHED boolean as volatile and it will work as expected, other threads will see the change the next time they access the variable.
However I will warn you against using volatile for anything except the most simple cases (single variable update). It provides no atomicity so if you need to do more than a single assignment during an update it will not provided the necessary guarantees. This includes increments/decrements which are actually 3 operations, read/modify/write at the memory model level so requires proper synchronization.
In that case you should use a synchronized block around both the read AND write.
private final Object lock = new Object();
private int shared1;
private int shared2;
public void write(int var1, int var2)
{
sychronized (lock)
{
shared1 = var1;
shared2 = var2;
}
}
public int readSum()
{
sychronized (lock)
{
int total = shared1 + shared2;
return total;
}
}
Upvotes: 0
Reputation: 6969
Add volatile
keyword to the CONNECTION_ESTABLISHED
method and see.
Upvotes: 1