>source

ExecutorService에서 실행되는 두 개의 스레드를 결합하고 싶었습니다.

public class CURD {
  public static ExecutorService executorService = Executors.newCachedThreadPool();
  
 @Autowired
 Logging logging;
  public void Update(List<? extends HBase> save, List<? extends HBase> delete) {
        Thread t = new Thread(() -> {
            System.out.println("Started Main Thread...");
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("End Main Thread...");
        },"Thread-1");
        logging.setPredecessor(t);
        executorService.submit(t);
    }
}

이급: 이 클래스 스레드는 첫 번째 스레드가 완료 될 때까지 기다려야합니다. 그러나 첫 번째 스레드가 완료 될 때까지 기다리지 않습니다. 이것이 올바른 방법인지 확실하지 않습니다.

누군가 ExecutorService에서 실행되는 두 개의 스레드를 결합하는 방법을 알려 주실 수 있습니까?

import static com.demo.executorService;
public class Logging {
   
   private Thread predecessor;
   public void  setPredecessor(Thread t) {
        this.predecessor = t;
    }
  private void loggingInfo() {
      Thread run = new Thread( () ->{
                try {
                    if (predecessor != null) {
                        System.out.println(Thread.currentThread().getName() + " Started");
                        predecessor.join();
                        System.out.println(Thread.currentThread().getName() + " Finished");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            addTask(run);
   }
   public void addTask(Runnable run) {
        System.out.println("Runnable Thread logAround.....");
        CompletableFuture.runAsync((run), executorService).exceptionally(ex -> {
            System.out.println("exception occurred " + ex);
            return null;
        });
    }
}


  • 답변 # 1

    스레드 집합간에 동기화하려면 다음을 사용할 수 있습니다. 이를위한 Java Class CyclicBarrier.

    A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.

    이를 달성하려면 먼저 CyclicBarrier 수를 가진 개체파티즉 :

    private final CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_PARIES);
    
    

    공식적으로 자바 문서에서 당사자는 다음과 같이 읽을 수 있습니다.

    the number of threads that must invoke {@link #await} before the barrier is tripped

    비공식적으로, 모든 스레드가 앞으로 나아갈 수 있기 전에 해당 장벽을 호출하고 대기해야하는 스레드 수입니다. 이후에 대기해야하는 각 스레드에 배리어 오브젝트 참조를 전달하고 호출해야합니다. wait (즉, barrier.await() ), 따라서. 다음과 같이 :

     public void Update(..., CyclicBarrier barrier) {
            Thread t = new Thread(() -> {
                System.out.println("Started Main Thread...");
                try {
                     Thread.sleep(1500);
                     barrier.await(); // <--- wait on the barrier
                } catch (InterruptedException | BrokenBarrierException e) {
                     e.printStackTrace();
                 }
                System.out.println("End Main Thread...");
            },"Thread-1");
            ...
        }
    
    

    기다려야하는 다른 스레드에도 동일한 프로세스를 수행하십시오. 당사자 수 (즉, NUMBER_OF_PARIES )는 장벽에서 대기해야하는 스레드 수와 일치합니다. 그렇지 않으면 교착 상태가 발생합니다. 이제 사용하고 있으므로 cyclic barrier 예를 들어 코드의 일부를 정리할 수 있습니다. 예를 들어 필드와 관련된 모든 논리를 제거 할 수 있습니다. predecessorLogging 수업.

    스레드 2가 스레드 1에서 대기하도록하려면 CountDownLatch를 사용할 수 있습니다.

    A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.

    먼저 CountDownLatch 1 개만있는 개체 :

    private final CountDownLatch block_thread2 = new CountDownLatch(1);
    
    

    스레드 2에 전달되고이 스레드가 스레드 1을 기다리도록하려면 다음을 호출하십시오. block_thread2.await();

         Thread run = new Thread( () ->{
                    try {
                         ....
                         block_thread2.await();
                         }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
                ...
    
    

    그리고 스레드 1 :

     public void Update(...) {
            Thread t = new Thread(() -> {
                System.out.println("Started Main Thread...");
                try {
                    Thread.sleep(1500);
                    wait.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("End Main Thread...");
            },"Thread-1");
            ...
        }
    
    

    따라서이 대기 스레드 2는 스레드 1을 기다리지 만 스레드 1은 스레드 2를 기다리지 않습니다.

  • 이전 jekyll - Liquid의 다차원 배열에서 중복을 제거하는 방법이 있습니까?
  • 다음 django는 수퍼 유저 상태를 제거합니다