javamethodslockingsynchronize

Java synchronize on object


How to synchronize two different methods from the same class in order to lock on the same object? Here is an example:

public class MyClass extends Thread implements Observer{
  public List<AnotherClass> myList = null;
  
  public MyClass(List<AnotherClass> myList){
    this.myList = myList;
  }
  
  public void run(){
    while(true){
       //Do some stuff 
       myList.add(NotImportantElement);
    }
  }

  public void doJob{
    for(int i=0; i<myList.size; i++){
      ElementClass x = myList.get(i);
      //Do some more stuff
    }
  }
}

The question is how can I stop run() from accesing myList when doJob is executed and viceversa?

Imagine this: I start the thread and start adding elements to my list. At a random moment I call doJob() from another class that holds a reference to my thread.

How should I do the lock? Thanks!

L.E.

Ok, I understood the concept of the lock, but now I have another question.

Suppose I have a class with public static myList and only one instance of that class. From that instance I create n instances of Thread that take every element of that list and do some stuff with it.

Now, at a specific moment, myList is updated. What happens with those Threads that already were processing myList elements? How should I lock access on myList while updating it?


Solution

  • NOTE: This code assumes you only have one instance of MyClass. according to your post that sounds like the case.

    public class MyClass extends Thread implements Observer{
      private List<AnotherClass> myList = null;
      private Object lock = new Object();
    
      public MyClass(List<AnotherClass> myList){
        this.myList = new ArrayList(myList);
      }
    
      public void run(){
        while(true){
           //Do some stuff 
           synchronized(lock) {
            myList.add(NotImportantElement);
           }
        }
      }
    
      public void doJob{
        synchronized(lock) {
          for(int i=0; i<myList.size; i++){
            ElementClass x = myList.get(i);
            //Do some more stuff
          }
        }
      }
    }
    

    EDIT: Added making a copy of List so that external entities could not change the list as per JB Nizet

    EDIT 2: Made variables private so nobody else can access them