Program Club

자바 스레드가 완료 될 때까지 기다립니다.

proclub 2021. 1. 5. 08:22
반응형

자바 스레드가 완료 될 때까지 기다립니다.


데이터를 다운로드하는 스레드가 있는데 데이터를로드하기 전에 다운로드가 완료 될 때까지 기다리려고합니다. 이를 수행하는 표준 방법이 있습니까?

더 많은 정보:

URL (Serialized POJO)에서 데이터를 가져 오는 다운로드 클래스가 있습니다. 다운로드는 실행 가능하고 관찰 가능합니다. 다운로드 된 바이트와 다운로드 크기를 추적합니다. 사용자에게 진행 상황을 표시하는 진행률 표시 줄이 있습니다. GUI는 다운로드를 관찰하여 진행률 표시 줄을 업데이트합니다.

POJO가 다운로드되면 가져 와서 다음 단계로 이동하고 싶습니다. 각 단계는 이전 단계가 완료 될 때까지 기다려야합니다. 문제는 다운로드 스레드를 기다리기 위해 응용 프로그램을 일시 중지하는 방법을 생각할 수 없다는 것입니다. 다운로드가 완료되면 데이터를 객체로 반환하는 download.getObject ()를 호출하고 싶습니다. 그런 다음 전송하고 다음 다운로드를 시작할 수 있습니다.

다운로드 할 URL을 관리하고 Download에 대한 모든 호출을 수행하는 도우미 클래스가 있습니다. 이 호출은 getObject를 호출하고 캐스팅을 수행합니다. Gui는 helper.getUser ()를 호출합니다. 도우미는 스레드 실행을 시작하고 완료되면 캐스트 된 개체를 반환 할 수 있도록 '알고'싶습니다.

제안 / 예제가 있습니까? 나는이 디자인의 시작 단계에 있으므로 기꺼이 변경할 의향이 있습니다.

감사합니다.

최신 정보:

나는 다음 http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html#get 스레드가 완료 될 때까지 블록 및 사용 모달. 코드는 매우 지저분했고이 접근 방식이 마음에 들지 않습니다. 다운로드 프로세스의 워크 플로를 처리 할 '깨끗한'방법을 계속 찾으려고 노력할 것입니다.


Thread스레드가 실행을 마칠 때까지 차단되는 조인 을위한 메서드가 있습니다 .


패키지 CountDownLatch에서를 사용할 수 있습니다 java.util.concurrent. 대기중인 스레드에서 실행을 계속하기 전에 하나 이상의 스레드가 완료되기를 기다릴 때 매우 유용합니다.

예를 들어 다음 세 가지 작업이 완료 될 때까지 기다립니다.

CountDownLatch latch = new CountDownLatch(3);
...
latch.await(); // Wait for countdown

다른 스레드 latch.countDown()는 작업이 완료되면 각 스레드를 호출 합니다. 카운트 다운이 완료되면이 예에서는 3 개가 실행됩니다.


SwingWorkerdoInBackground()작업을 수행하는 데 사용할 수 있습니다. 호출 get()하고 다운로드가 완료 될 때까지 기다리거나 done()SwingWorker가 완료되면 이벤트 디스패치 스레드에서 호출 될 메서드를 재정의 할 수 있습니다 .

Swingworker는 찾고있는 기능이 많기 때문에 바퀴를 재발 명 할 필요가 없다는 점에서 현재 접근 방식에 이점이 있습니다. 다운로드 진행을 위해 실행 파일에서 관찰자 대신 getProgress()setProgress()메서드 를 사용할 수 있습니다 . done()제가 위에서 언급 한 바와 같이 방법이 다운로드가 완료된 후 데이터를로드 할 수 있습니다, 실행하는 작업자가 완료된 후 호출되고 EDT 수행됩니다.


join () 메서드에 대한 더 나은 대안 이 일정 기간 동안 발전했습니다.

ExecutorService.html # invokeAll 이 한 가지 대안입니다.

주어진 작업을 실행하고 모든 완료시 상태와 결과를 보유한 Future 목록을 반환합니다. Future.isDone ()은 반환 된 목록의 각 요소에 대해 true입니다.

완료된 작업은 정상적으로 종료되거나 예외가 발생하여 종료 될 수 있습니다. 이 작업이 진행되는 동안 지정된 컬렉션이 수정되면이 메서드의 결과는 정의되지 않습니다.

ForkJoinPool 또는 Executors.html # newWorkStealingPool 은 동일한 목적을 달성하기위한 다른 대안을 제공합니다.

예제 코드 스 니펫 :

import java.util.concurrent.*;

import java.util.*;

public class InvokeAllDemo{
    public InvokeAllDemo(){
        System.out.println("creating service");
        ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

        List<MyCallable> futureList = new ArrayList<MyCallable>();
        for ( int i=0; i<10; i++){
            MyCallable myCallable = new MyCallable((long)i);
            futureList.add(myCallable);
        }
        System.out.println("Start");
        try{
            List<Future<Long>> futures = service.invokeAll(futureList);  
        }catch(Exception err){
            err.printStackTrace();
        }
        System.out.println("Completed");
        service.shutdown();
    }
    public static void main(String args[]){
        InvokeAllDemo demo = new InvokeAllDemo();
    }
    class MyCallable implements Callable<Long>{
        Long id = 0L;
        public MyCallable(Long val){
            this.id = val;
        }
        public Long call(){
            // Add your business logic
            return id;
        }
    }
}

join()모든 스레드가 완료 될 때까지 대기 하는 사용할 수 있습니다 . 스레드를 생성 할 때 모든 스레드 개체를 전역 ArrayList에 유지합니다. 그 후 아래와 같이 루프를 유지하십시오.

for (int i = 0; i < 10; i++) 
{
    Thread T1 = new Thread(new ThreadTest(i));                
    T1.start();                
    arrThreads.add(T1);
} 

for (int i = 0; i < arrThreads.size(); i++) 
{
    arrThreads.get(i).join(); 
}

자세한 내용은 여기에서 확인하십시오. http://www.letmeknows.com/2017/04/24/wait-for-threads-to-finish-java


I imagine that you're calling your download in a background thread such as provided by a SwingWorker. If so, then simply call your next code sequentially in the same SwingWorker's doInBackground method.


Generally, when you want to wait for a thread to finish, you should call join() on it.


Any suggestions/examples? I followed SwingWorker... The code was very messy and I don't like this approach.

Instead of get(), which waits for completion, use process() and setProgress() to show intermediate results, as suggested in this simple example or this related example.


The join() method allows one thread to wait for the completion of another.However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.

ReferenceURL : https://stackoverflow.com/questions/4691533/java-wait-for-thread-to-finish

반응형