Competition and memory sharing between Threads

Asked

Viewed 479 times

0

I have the following code:

class Objt
{
    public List<t> list_t1;
    public List<t> list_t2;

    public Objt() 
    {
        // faz inicializações
    }

    public void handleLists(List<t> list)
    {
        for(t e: list)
        {
           ... // manipula elementos da lista
        {
    }
}

Problem: I am free to manipulate both lists at the same time in my problem, including that is the intention. In this code above, only one thread can enter this line of code of this object at a time to manipulate a list, the other would be waiting to manipulate another list.

Question: I could well duplicate this method handleLists() and name them handleList1() and handleList2() and allocate them each to a thread, but it’s kind of tricky, isn’t it? Is there a more elegant solution? A Pattern?

What I want to understand now, given the comments, is whether I can use the same method handleLists() in both threads just passing different lists for each thread and they will execute in parallel.

Note: I had put list_t1 and list_t2 just to illustrate a possible use.

  • 1

    The question does not make clear what you really want, what the specific situation is, but if I have understood what is written, the synchronized seems unnecessary. Why would you need to create another method to do the same thing? Create each thread calling the same method by passing each list in a thread.

  • Dude, the situation is this presented, I don’t have much to add. I need to manipulate the lists of the same object in "parallel". The synchronized is there assuming that I implemented the case of two threads using the same method of that object each passing a list. With the solution you talked about that will give problem, threads will change the reference to variable list of the method all the time, and so I will get a completely undesirable result, because I call the same method of the same object every time.

  • 1

    If there are two different lists there is no reason why one should interfere with the other. I think you have not understood how the threads work. Or else you are reporting a completely different problem than you really want and want to mess with the same list in two threads. But it is not what is written. And if it is also, you probably will not have the gain you are waiting for. Read: http://answall.com/q/1946/101. And read Piovesan’s reply confirming this. He considered that the code will use the two lists in the method, I think not (I think because the code was not shown, so have what to add).

  • I added more details after evaluating some things here man!

2 answers

5

Piovezan’s answer gives a great explanation of the problem he is having in the use of the method, so I will just supplement with the part I understood different in the question (which in passing is not very clear at this point).

If the method will simultaneously receive different lists, in case a call in a thread will receive list_t1 and the other call in another thread will receive list_t2 and the method will not manipulate the parameter list which will contain either one or the other list on each call, they will not get confused, are called completely isolated and there will be no competition problems. Therefore, not only is there no problem in calling this method in more than one thread simultaneously, achieving parallelism, as neither need mark it as synchronized. You won’t even need to synchronize anything internally, which can even end parallelism depending on how it’s used (I’ve already talked about this).

Of course it may not be quite this depending on the content of the method, which was not posted.

As an addition, creating another method will not help at all. In fact, depending on what you do, it can even bring more problems.

  • "and the method no will manipulate..." that "no" is what? But it seems that’s what I wanted to know so man, wanted to know if they run alone or not, even if each thread manipulates their list! So thanks.

  • 1

    It’s "no," edited. Thank you.

  • Just an expensive question: @Piovezan gave an example of two uses of synchronized and I already knew that, but I had a question. If a thread enters a synchronized block (either a method or even a block) of an object, but another thread was using another method of that same object alone, with other services, that thread stops because the other thread entered the synchronized block, ie, used the lock/monitor/token of that object or not?

  • If I understand what you’re saying, yes, one blocks the other.

3


In my experience it is not common for you to have two independent lists requiring synchronized access to an object. It may be evidence of a violation of the Single Liability Principle. But this is a design issue and does not come to the point.

Keep in mind that the 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 any given time can perform the desired action, otherwise you will have to wait for the owner of the token release him so he can acquire that token and perform the action. Except 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 who owns the lock can enter the synchronized code snippet and execute it (and perform operations on your 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 lock for the synchronized method handleLists().

The choice of lock (or of Locks) most appropriate(s) for your case will depend on your intention. When a thread has access to list_t1, you want him to also have access to list_t2? In this case, you can use a lock only for both lists. This lock can be the object itself Objt, or another object you define as an attribute of Objt.

Or when a thread has access to list_t1, you don’t want him to have access to list_t2? Then you’ll need two Locks different. The lists themselves, if they are non-null and declared as final, can be used as Locks for access to themselves. Or else you can create two attributes lock_t1 and lock_t2.

Note that the two code snippets below are equivalent:

Stretch 1:

public class Objt {

    public synchronized handleList() {
        ...
    }
}

Stretch 2:

public class Objt {

    public handleList() {
        synchronized(this) { // "this" é referência para o próprio
            ...              // objeto de classe Objt
        }
    }
}

Editing:

You clarified that you want to have a method that takes a list as a parameter and makes changes to it. A thread will call this method by passing a list list_t1 as a parameter and another thread will call this method by passing another list list_t2 as a parameter.

In this case IF this is the only point where the lists are modified, the parallelism will work smoothly and there will be no need to declare the method synchronized, as @Maniero said in his reply, 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 else stop declaring everything as public and try to learn how to use 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 threads who call such a method, that we show you how it can stay.

  • That’s what I wanted, man, maybe my question was a little fuzzy, take a look at it now, man!

  • I supplemented the answer.

  • That’s right, man, @bigown just said that part. I wanted to understand if the parallelism was going to work or give problem in the references of the lists, but then it is answered. About code details, disregard, I wrote this short code here just to illustrate the lists and the method to use them.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.