How to share lock between threads started by instances of different classes in Java?

95 Views Asked by At

I tried creating a shared lock in the Application class and passing it to the method parameter that creates a thread and uses this lock. I want a thread created by an instance of a class to synchronize with a thread created by an instance of another class.

Class Alpha has a start(Object sharedLock) which creates a new thread.


public abstract class Alpha {
   public abstract void test();

   public void start(Object sharedLock) {
      Thread t = new Thread(() -> {
         while(true) {
            synchronized(sharedLock) {
               test();
            }
            try {
               TimeUnit.SECONDS.sleep(db.timeInterval)
            } catch(InterruptedException e) {
                 Thread.currentThread().interrupt();
            }
        }
      })
   }
}

Class Alpha has two base classes Beta and Gama, which invokes start() method from Application class. Below is the code snippet

@Override
public void run(String... args) {
    beta.start(sharedLock);
    gama.start(sharedLock)
}

test() is overridden in child classes - beta and gama.

And here is the implementation of test()

public class Beta extends Aplha {
   @Override
   public void test() {
      ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
      final int[] count = {1};
   
      Runnable task = new Runnable() {
         @Override
         public void run() {
            System.out.println(count[0]);
            count[0]++;

            if (count[0] > 20) {
               executor.shutdown();
            }
         }
      }
      executor.scheduledAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
   }
}

public class Gama extends Alpha {
   @Override
   public void test() {
      System.out.println("Gama thread")
   }
}

Only one thread should be able to execute test() at a time. So if beta thread calls start() first then it should print 1 to 20 and then gama thread execute start()

Also, when a thread is seeping, the other thread can execute by having access to lock

How can I achieve this behaviour?

2

There are 2 best solutions below

3
Maurice Perry On

Try a semaphore:

public static void start(Semaphore sharedLock) {
    Thread t = new Thread(() -> {
        while (true) {
            try {
                sharedLock.acquire();
                test();
                sharedLock.release();
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    });
    t.start();
}

public static void main(String[] args) {
    Semaphore semaphore = new Semaphore(1);
    start(semaphore);
    start(semaphore);
}
0
Solomon Slow On

I have added the implementation of the start() method for both classes."

Actually, no. You added the test methods. But no matter because...

Only one thread should be able to execute test() at a time. So if beta thread calls start() first then it should print 1 to 20 and then gama thread execute start()

Your beta.test() method doesn't print anything. It creates a new ScheduledExecutorService, and it submits a task to it. The scheduled executor performs that task in a completely different thread, and the task makes no reference whatever to the sharedLock object.