How to make sure that a method is executed only once and from only one thread?

I have a method below that I want to execute under the following conditions:

  • This method should be executed only once. And once it is executed, it cannot be executed again, so if someone tries to execute it again, it must go back by registering a useful error message already executedor something useful.
  • And it should be executed by only one thread. Therefore, if several threads call the method below, then should it be called only by one thread, and the other threads should wait for the initialization to complete?

Below is my method:

  public void initialize() {
    List<Metadata> metadata = getMetadata(true);
    List<Process> process = getProcess();
    if (!metadata.isEmpty() && !process.isEmpty()) {
        Manager.setAllMetadata(metadata, process);
    }
    startBackgroundThread();
  }

Can this be done? I am working with Java 7.

+6
3

@ShayHaned . AtomicBoolean, :

AtomicBoolean wasRun = new AtomicBoolean(false);
CountDownLatch initCompleteLatch = new CountDownLatch(1);

public void initialize() {
  if (!wasRun.getAndSet(true)) {
      List<Metadata> metadata = getMetadata(true);
      List<Process> process = getProcess();
      if (!metadata.isEmpty() && !process.isEmpty()) {
          Manager.setAllMetadata(metadata, process);
      }
      startBackgroundThread();
      initCompleteLatch.countDown();
  } else {
      log.info("Waiting to ensure initialize is done.");
      initCompleteLatch.await();
      log.warn("I was already run");
  }
}

, startBackgroundThread. , :

AtomicBoolean wasRun = new AtomicBoolean(false);
CountDownLatch initCompleteLatch = new CountDownLatch(1);

public void initialize() {
  if (!wasRun.getAndSet(true)) {
      List<Metadata> metadata = getMetadata(true);
      List<Process> process = getProcess();
      if (!metadata.isEmpty() && !process.isEmpty()) {
          Manager.setAllMetadata(metadata, process);
      }
      // Pass the latch to startBackgroundThread so it can
      // call countDown on it when it done.
      startBackgroundThread(initCompleteLatch);
  } else {
      log.info("Waiting to ensure initialize is done.");
      initCompleteLatch.await();
      log.warn("I was already run");
  }
}

, AtomicBoolean.getAndSet(true) , , true. , false ( false), true. false, if, . , wasRun.getAndSet true, true, 2- , , .

CountDownLatch 1, , await . , countDown, 0, .

+6

, . , , , , , , , , , if else.

 static boolen flag;
public void initialize() {
if (flag)
{// return from here or some message you want to generate 
}else{
    List<Metadata> metadata = getMetadata(true);
    List<Process> process = getProcess();
    if (!metadata.isEmpty() && !process.isEmpty()) {
        Manager.setAllMetadata(metadata, process);
    }
       flag = true;
    startBackgroundThread();       }}

,

+2

β€’ . , , , ?

public static final Object singleThreadLock = new Object();

public void initialize()
{
    synchronized( singleThreadLock )
    {

        List<Metadata> metadata = getMetadata(true);
        List<Process> process = getProcess();
        if (!metadata.isEmpty() && !process.isEmpty()) 
        {
            Manager.setAllMetadata(metadata, process);
        }
       startBackgroundThread();
    } 
  }

GUARANTEE, initialize() , singleThreadLock , JVM , . (), concurrency.

+1

Source: https://habr.com/ru/post/1014708/


All Articles