0

I wanted to make sure(that i understood correctly) and know how synchronized methods in java guarantees none interference on objects.

For example I have this code:

private void update_curr_mat(int stock_ind, double price, double time)
{
    synchronized(current_mat_data)
    {
        current_mat_data[stock_ind][HIGH_PRICE_IND] = price;
        current_mat_data[stock_ind][LOW_PRICE_IND] = price;
        current_mat_data[stock_ind][CLOSE_IND] = price;
        current_mat_data[stock_ind][HIGHEST_IND] = price;
        current_mat_data[stock_ind][LOWEST_IND] = price;

        current_mat_data[stock_ind][CURR_TIME_IND] = time;
    }
}

In this example it is obvious, that current_mat_data is synchronized, and when the method invoked, another thread can't write to current_mat_data object.

In this example:

private synchronized void update_curr_mat(int stock_ind, double price, double time)
{
        current_mat_data[stock_ind][HIGH_PRICE_IND] = price;
        current_mat_data[stock_ind][LOW_PRICE_IND] = price;
        current_mat_data[stock_ind][CLOSE_IND] = price;
        current_mat_data[stock_ind][HIGHEST_IND] = price;
        current_mat_data[stock_ind][LOWEST_IND] = price;

        current_mat_data[stock_ind][CURR_TIME_IND] = time;
}

The synchronized is done in the method definition. I know that it guarantees that two threads can't invoke this method simultaneously.

So my question is, it is guarantees that other thread can't access the object current_mat_data while the function in the second exmaple invoked ? if it is true, can you explain how it works ? If i'm not right about something i wrote or something isn't clear, please let me know.

DeSpeaker
  • 1,159
  • 1
  • 11
  • 11
  • Unrelated: please read about java coding conventions. You only use the _ in SOME_CONSTANT. Variable names go currentMaterialData for example (and yes, avoid abbreviating - there is no point in saving a few key strokes but making reading/understanding code so much harder in exchange). – GhostCat Jul 20 '17 at 19:20

4 Answers4

2

In both examples, there is no absolute guarantee (given only what you've shown) that nothing can edit the object. That is, this statement

In this example it is obvious, that current_mat_data is synchronized, and when the method invoked, another thread can't write to current_mat_data object.

is incorrect.

The only guarantees are that no two threads can hold the same lock at the same time; and that a thread must hold the appropriate lock to execute a synchronized block or method (and therefore, if another thread holds the lock the thread must wait until it becomes available before it can take the lock and enter the block or method).

You must use encapsulation and good programming to build any additional guarantees up from there.

What can become confusing is, every object can be used as a lock, but you don't necessarily have to hold an object's lock to edit that object. That is to say, Java doesn't require you to have the lock to edit the object. To enforce such a rule, you need every way that the object can be edited to be contained in a synchronized block or method that uses that object as a lock.

The difference between your two examples is simply which object is used as a lock. The first example uses the object referenced by current_mat_data; the second uses the object referenced by this (the object instance on which the update_cur_mat method is invoked). (A static method would use the class object.)

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
1

As far as I can tell, no, while the other thread might be prevented from invoking update_curr_mat, it could still access another, non-synchronized, method that manipulates the update_curr_mat object. For instance if you have another method:

public void mess_with_curr_mat(int stock_ind, double price)
{ 
    current_mat_data[stock_ind][HIGH_PRICE_IND] = price;
}

The other thread could call this method and nothing is stopping it from doing so, since it is not synchronized. However, if you were to make the update_curr_mat method static, and the current_mat_data variable static as well, then you'd avoid this risk, because this would synchronize on the actual class object itself.

Malphrush
  • 328
  • 3
  • 12
1

In this example it is obvious, that current_mat_data is synchronized, and when the method invoked, another thread can't write to current_mat_data object.

Wrong. Putting synchronized(someObject) does not prevent any other thread from doing something with someObject.

The only thing that happens here is that only one thread can enter that protected block! This is a way to lock a section of code. Not a way to lock that object!

In other words: assuming that update_curr_mat() is the only method that updates that object - then yes, this synchronized statement does effectively prevent multiple threads from tampering with current_mat_dat.

Again: you can't lock an object against updates this way. The only way to prevent parallel changes is to ensure that each and any line of code that will modify that object is guarded by the same lock.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Ok, i got it now, Thanks very much. By the way, i can use any lock to prevent parallel changes ? (although it doesn't make sense logically) ? – DeSpeaker Jul 21 '17 at 13:39
  • I dont get your question. You use locks to **prevent** that more than thread can run a certain piece of code at any given time. So when **all code that changes something** is protected (in the same way), then you can be sure that it is protected. In that sense: start reading https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html ... top to bottom will help ;-) – GhostCat Jul 21 '17 at 13:41
0

Java synchronized does not guarantee any thread-safety, that is your job as a programmer. What it guarantees is, that at no time two threads can enter a synchronized block with the same locking object simultaneously.

So if you have:

final Object myLock = new Object();

void funcA() {
  synchronized(myLock) { 
    // ... 
  }
}

void funcB() {
  synchronized(myLock) { 
    // ... 
  }
}

Then under no circumstance can a thread be in the synchronized block of funcA while another thread is in the synchronized block of funcB, nor can any two threads be in the same block of funcA or funcB at the same time.

if you have code like this however:

final Object myLockA = new Object();
final Object myLockB = new Object();

void funcA() {
  synchronized(myLockA) { 
    // ... 
  }
}

void funcB() {
  synchronized(myLockB) { 
    // ... 
  }
}

Then still the same holds true, but of course one thread can have myLockA while another thread has myLockB at the same time. Whether or not that is a good thing completely depends on your code inside the synchronized block.

The reason for having the option for individual lock objects is so that you have a fine-grained control over which blocks of code need to have exclusive access. If in the above example funcA writes into entirely different objects than funcB, then there is no reason to lock threads out of the other functions when accessing one of them.

TwoThe
  • 13,879
  • 6
  • 30
  • 54
  • Ok, so should i use synchronized methods when they are the only code sections who writes to a specsific objects ? – DeSpeaker Jul 21 '17 at 14:17
  • It depends on which threads calls them. If only a single thread calls that function at all times, then synchronized is not necessary. If multiple threads call that function then synchronized (or equivalent) is necessary. – TwoThe Aug 07 '17 at 07:36