In my experience it is not uncommon for you to have two independent lists requiring synchronized access to an object. It may be a sign of a violation of the Principle of Single Responsibility. But this is a matter of design and is beside the point.
Keep in mind that synchronized access to a code snippet depends on a token, that is, an object of which there is only one instance, so that whoever has it at a given time can perform the desired action, if otherwise it will have to wait for the owner of the token to release it so that it can acquire that token and take action. With the difference that the term used is not "token" but "lock" (or semaphore, monitor, etc). What I mean is that his job is to be a token. This is what synchronized access is all about: the thread that has the lock can enter the synchronized code snippet and execute it (and do operations on its lists, for example).
Any object can be a lock. When a method is synchronized
, the lock is the very object that contains that method. In the case of your example, if you have such a code ...
Objt bijeto = new Objt();
bijeto.handleLists(list);
... the object bijeto
will be the lock for the synchronized method handleLists()
.
Choosing the most appropriate lock (s) for your case will depend on your intent. When a thread has access to list_t1
, do you want it to also have access to list_t2
? In this case, you can use a lock only for the two lists. This lock can be the Objt
object itself, or else another object that you define as the Objt
attribute.
Or when a thread has access to list_t1
, do not you want it to have access to list_t2
? In this case you will need two different locks. The lists themselves, if they are non-null and declared as final
, can be used as locks for access to themselves. Or you can create two attributes lock_t1
and lock_t2
.
Note that the two code snippets below are equivalent:
Excerpt 1:
public class Objt {
public synchronized handleList() {
...
}
}
Excerpt 2:
public class Objt {
public handleList() {
synchronized(this) { // "this" é referência para o próprio
... // objeto de classe Objt
}
}
}
Editing:
You have clarified that you want to have a method that receives a list as a parameter and makes changes to it. A thread will call this method by passing a list_t1
list as a parameter and another thread will call that method by passing another list_t2
list as a parameter.
If this is the only point where the lists are modified, the parallelism will work without problems and there will be no need to declare the synchronized
method, as @bigown said in its response, which perfectly answers the question. It will work because the method is not making any changes in shared state, only in the state of the parameters passed to it, which in this case are independent of each other.
But avoid declaring the lists in the class that contains this same method, this only creates confusion (because if they are attributes of a class it would not be necessary to pass them as a parameter to methods of that same class).
Or stop declaring everything as public
and try to learn how to use the Java access modifiers to correctly reflect your intentions in the code.
If you want to make the code more elegant, give more details about what you want to do and include more code in the question, including the threads that call that method, which shows you how it can look.