다른 스레드가 완료되었는지 확인하는 방법
는 서드 named named named named named named named named named named named named named named named 라는 이름의 물건을 있다.StartDownload()3월 3일
각 스레드의 실행이 완료되면 알림을 받으려면 어떻게 해야 합니까?
스레드 중 하나(또는 모두)가 완료되었는지 아직 실행 중인지 알 수 있는 방법이 있습니까?
여기에는 여러 가지 방법이 있습니다.
- 메인 스레드에서 Thread.join()을 사용하여 각 스레드가 완료될 때까지 블로킹 방식으로 기다립니다.
- 각 스레드가 완료될 때까지 대기하려면 [Thread.isAlive()]를 폴링 방식으로 선택합니다(일반적으로 권장되지 않음).
- 문제의 각 스레드에 대해 비정통적인 경우 setUncaughtExceptionHandler를 호출하여 오브젝트 내의 메서드를 호출하고 완료 시 각 스레드가 수집되지 않은 예외를 발생시키도록 프로그래밍합니다.
- java.util.concurrent의 잠금, 동기화 또는 메커니즘을 사용합니다.
- 보다 정통적인 방법으로 기본 스레드에 수신인을 작성한 후 각 스레드가 수신인에게 완료되었음을 알리도록 프로그래밍합니다.
아이디어 #5의 구현 방법우선 인터페이스를 작성하는 방법이 있습니다.
public interface ThreadCompleteListener {
void notifyOfThreadComplete(final Thread thread);
}
그런 다음 다음 클래스를 만듭니다.
public abstract class NotifyingThread extends Thread {
private final Set<ThreadCompleteListener> listeners
= new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}
@Override
public final void run() {
try {
doRun();
} finally {
notifyListeners();
}
}
public abstract void doRun();
}
각각의 됩니다.NotifyingThread「」를 실장하는 에,run()doRun()따라서 작업이 완료되면 알림을 기다리는 모든 사용자에게 자동으로 알립니다.
적어도 알림을 를 에서 해당 를 "알림"으로 합니다.implement ThreadCompleteListener그리고 각 스레드를 작성한 직후 청취자 목록에 추가합니다.
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
각 종료되면, 「」는 「」를 참조해 .notifyOfThreadComplete메서드는 방금 완료(또는 크래시)한 스레드 인스턴스에서 호출됩니다.
해 주십시오.implements Runnableextends Thread★★★★★★에NotifyingThread스레드 확장은 보통 새 코드에서는 권장되지 않습니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 경우, 이 항목을 변경할 수 있습니다.NotifyingThread implement (실행 클래스)Runnable스레드를 관리하는 코드를 변경해야 합니다.이 작업은 매우 간단합니다.
CyclicBarrier를 사용한 솔루션
public class Downloader {
private CyclicBarrier barrier;
private final static int NUMBER_OF_DOWNLOADING_THREADS;
private DownloadingThread extends Thread {
private final String url;
public DownloadingThread(String url) {
super();
this.url = url;
}
@Override
public void run() {
barrier.await(); // label1
download(url);
barrier.await(); // label2
}
}
public void startDownload() {
// plus one for the main thread of execution
barrier = new CyclicBarrier(NUMBER_OF_DOWNLOADING_THREADS + 1); // label0
for (int i = 0; i < NUMBER_OF_DOWNLOADING_THREADS; i++) {
new DownloadingThread("http://www.flickr.com/someUser/pic" + i + ".jpg").start();
}
barrier.await(); // label3
displayMessage("Please wait...");
barrier.await(); // label4
displayMessage("Finished");
}
}
label0 - 실행 스레드 수와 같은 파티 수와 실행 메인 스레드용 1개를 더한 순회 장벽이 생성됩니다(startDownload()가 실행 중).
라벨 1 - n번째 다운로드쓰레드가 대기실로 들어갑니다.
라벨 3 - NUMBER_OF_DOWNLOADING_THREADS가 대기실에 들어왔습니다.실행의 메인 스레드는 다운로드 작업을 거의 동시에 시작하도록 해방합니다.
라벨 4 - 메인 실행 스레드가 대기실로 들어갑니다.이것은 코드에서 가장 이해하기 어려운 부분입니다.두 번째 대기실에 어떤 실이 들어가든 상관없습니다.마지막으로 룸에 들어온 스레드가 다른 모든 다운로드 스레드의 다운로드 작업이 완료되었는지 확인하는 것이 중요합니다.
라벨 2 - n번째 다운로드Thread는 다운로드 작업을 마치고 대기실로 들어갑니다.이 스레드가 마지막 스레드일 경우(NUMBER_OF_DOWNLOADING_THREADS가 이미 입력되어 있는 경우) 메인 스레드는 다른 모든 스레드의 다운로드가 완료된 경우에만 실행을 계속합니다.
이 솔루션을 사용하는 것이 좋습니다.java.util.concurrent조쉬 블로흐 브라이언 괴츠
「 」를하고 있지 않은 경우java.util.concurrent.*직접 을 책임지고 스레드를 사용하는 이 좋습니다.그러면 아마join()아, 네, 이겁니다.먼저 확장하다Runnable「 」 「 」 。
public interface CallbackRunnable extends Runnable {
public void callback();
}
그런 다음 실행 파일을 실행하는 실행자를 만들고 실행이 완료되면 다시 전화하십시오.
public class CallbackExecutor implements Executor {
@Override
public void execute(final Runnable r) {
final Thread runner = new Thread(r);
runner.start();
if ( r instanceof CallbackRunnable ) {
// create a thread to perform the callback
Thread callerbacker = new Thread(new Runnable() {
@Override
public void run() {
try {
// block until the running thread is done
runner.join();
((CallbackRunnable)r).callback();
}
catch ( InterruptedException e ) {
// someone doesn't want us running. ok, maybe we give up.
}
}
});
callerbacker.start();
}
}
}
은 른른른 your your your your your your the the the the에 대해서입니다.CallbackRunnable에 '를 수 .따서 、 를를 、public void uncaughtException(Throwable e);행 입력과 실행자에 스레드를 설치합니다.Unaughted Exception Handler 。
실제로 건java.util.concurrent.Callable 을 꼭 .java.util.concurrent신신면
끝날 때까지 기다릴까요?이 경우 Join 메서드를 사용합니다.
체크하고 싶은 경우 isAlive 속성도 있습니다.
스레드 인스턴스를 반환하는 getState()를 사용하여 스레드 인스턴스를 조회할 수 있습니다.다음 값 중 하나를 포함하는 상태 열거:
* NEW
A thread that has not yet started is in this state.
* RUNNABLE
A thread executing in the Java virtual machine is in this state.
* BLOCKED
A thread that is blocked waiting for a monitor lock is in this state.
* WAITING
A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
* TIMED_WAITING
A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
* TERMINATED
A thread that has exited is in this state.
다만, 3명의 아이가 끝나기를 기다리는 마스터 스레드가 있는 것이 좋다고 생각합니다만, 나머지 3명이 끝나면 마스터는 실행을 계속합니다.
,도할 수 .Executors오브젝트를 지정하여 ExecutorService 스레드 풀을 만듭니다.그 후 를 사용합니다.invokeAll각 스레드를 실행하고 Futures를 검색하기 위한 메서드를 제공합니다.이치노은 풀을 한 다음, '하다'를 호출하는 입니다.awaitTermination이치노해 주세요.shutdown )을 클릭합니다. ( ) () () () () 。
지난 6년간 멀티 스레드 전선에서 많은 것이 바뀌었습니다.
「 」를 하는 대신에, 「 」를 사용합니다.join() A를 할 수 있습니다.PI 그 pi잠 pi pi
1. 이그제큐티브 서비스 invokeAll()
지정된 작업을 실행하여 모든 작업이 완료되면 상태 및 결과를 보유한 미래 목록을 반환합니다.
2. 카운트 다운 래치
다른 스레드에서 수행 중인 일련의 작업이 완료될 때까지 하나 이상의 스레드가 대기할 수 있는 동기화 보조 도구입니다.
A
CountDownLatch는 지정된 카운트로 초기화됩니다.이 될 됩니다.되기 때문입니다.countDown()모든 대기 스레드가 해제되고 이후의 호출이 즉시 반환되는 메서드입니다.이것은 원샷 현상입니다.을 사용하다카운트를 리셋하는 버전이 필요한 경우는, CyclicBarrier 의 사용을 검토해 주세요.
3. Fork Join Pool 또는newWorkStealingPool()executors는 다른 방법입니다.
모두 한다.FutureExecutorService 콜을 합니다.get()Future 표시
관련 SE 질문을 살펴보십시오.
실행자:작업이 반복적으로 생성되는 경우 모든 작업이 완료될 때까지 동기적으로 대기하려면 어떻게 해야 합니까?
스레드 클래스용 javadoc을 보는 것이 좋습니다.
스레드 조작에는 여러 가지 메커니즘이 있습니다.
에서는, 「」를 사용할 수 있습니다.
join()3개의 스레드를 순차적으로 실행한 후 3개가 모두 완료될 때까지 진행되지 않습니다.생성된 스레드의 스레드 상태를 정기적으로 폴링합니다.
된 모든 .
ThreadGroupactiveCount()ThreadGroup0이 될 .스레드간 통신용으로 커스텀콜백 또는 리스너 타입의 인터페이스를 설정합니다.
내가 아직 놓치고 있는 다른 방법들이 많이 있을 거야
가장 쉬운 방법은 이 제품을 사용하는 것 같습니다.ThreadPoolExecutor
- 큐가 있으며 병렬로 작동해야 하는 스레드 수를 설정할 수 있습니다.
- 콜백 방식은 다음과 같습니다.
후크 방식
는 protected 합니다.
beforeExecute(java.lang.Thread, java.lang.Runnable)★★★★★★★★★★★★★★★★★」afterExecute(java.lang.Runnable, java.lang.Throwable)각 태스크 실행 전후에 호출되는 메서드.예를 들어 ThreadLocal 재초기화, 통계 수집, 로그 항목 추가 등 실행 환경을 조작하는 데 사용할 수 있습니다. 방법 「」, 「」도 .terminated()실행자가 완전히 종료된 후 수행해야 하는 특별한 처리를 수행하도록 덮어쓸 수 있습니다.
우선은 우선입니다.afterExecute()후 "콜백"이 됩니다.terminated()모든 스레드가 언제 완료되었는지 알 수 있습니다.
그래서 당신이 해야 할 일은 다음과 같다.
실행자를 만듭니다.
private ThreadPoolExecutor executor; private int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors(); private void initExecutor() { executor = new ThreadPoolExecutor( NUMBER_OF_CORES * 2, //core pool size NUMBER_OF_CORES * 2, //max pool size 60L, //keep aive time TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() ) { @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); //Yet another thread is finished: informUiAboutProgress(executor.getCompletedTaskCount(), listOfUrisToProcess.size()); } } }; @Override protected void terminated() { super.terminated(); informUiThatWeAreDone(); } }스레드 시작:
private void startTheWork(){ for (Uri uri : listOfUrisToProcess) { executor.execute(new Runnable() { @Override public void run() { doSomeHeavyWork(uri); } }); } executor.shutdown(); //call it when you won't add jobs anymore }
메서드 「」informUiThatWeAreDone();모든 스레드가 완료되면 UI 업데이트 등 필요한 작업을 수행합니다.
주의: 잊지 말고synchronized.synchronized 사람의 synchronized이것은 로 이어집니다.
이게 도움이 됐으면 좋겠네요!
여기 간단하고, 짧고, 이해하기 쉽고, 나에게 딱 맞는 솔루션이 있습니다.다른 스레드가 끝날 때 화면을 그려야 했지만 메인 스레드가 화면을 제어하기 때문에 그릴 수 없었습니다.그래서:
(1) (1)을 만들었습니다.boolean end1 = false;사실대로 말하다이는 메인 스레드에서 "지연 후" 루프를 통해 픽업되며, 여기서 응답됩니다.
(2) 내 스레드는 다음을 포함한다.
void myThread() {
end1 = false;
new CountDownTimer(((60000, 1000) { // milliseconds for onFinish, onTick
public void onFinish()
{
// do stuff here once at end of time.
end1 = true; // signal that the thread has ended.
}
public void onTick(long millisUntilFinished)
{
// do stuff here repeatedly.
}
}.start();
}
(3) 다행히 "post Delayed"는 메인 스레드에서 실행되므로 거기서 1초에 1회 다른 스레드를 체크합니다.다른 스레드가 끝나면 다음에 하고 싶은 모든 작업을 시작할 수 있습니다.
Handler h1 = new Handler();
private void checkThread() {
h1.postDelayed(new Runnable() {
public void run() {
if (end1)
// resond to the second thread ending here.
else
h1.postDelayed(this, 1000);
}
}, 1000);
}
(4) 마지막으로, 다음과 같이 전화하여 코드의 어딘가에서 실행되는 모든 것을 시작합니다.
void startThread()
{
myThread();
checkThread();
}
속성 변경 지원이 내장된 SwingWorker를 사용할 수도 있습니다.상태 변경 리스너 예에 대해서는 addPropertyChangeListener() 또는 get() 메서드를 참조하십시오.
스레드 클래스에 대한 Java 문서를 참조하십시오.스레드 상태를 확인할 수 있습니다.3개의 스레드를 멤버 변수에 넣으면 3개의 스레드 모두 서로의 상태를 읽을 수 있습니다.
그러나 스레드 사이에 레이스 상태가 발생할 수 있기 때문에 조금 주의해야 합니다.다른 스레드 상태에 근거한 복잡한 논리는 피하도록 하세요.여러 스레드가 같은 변수에 쓰이지 않도록 하십시오.
언급URL : https://stackoverflow.com/questions/702415/how-to-know-if-other-threads-have-finished
'source' 카테고리의 다른 글
| MariaDB(MySQL)에서 소유권과 권한을 올바르게 설정하려면 어떻게 해야 합니까? (0) | 2023.02.04 |
|---|---|
| Node.js에서 HTTPS 서버를 작성하는 방법 (0) | 2023.02.04 |
| HTML Collection 요소의 루프용 (0) | 2023.02.04 |
| Fedora 19 명령줄에서 데이터베이스 다이어그램을 생성하려면 어떻게 해야 합니까? (0) | 2023.02.04 |
| PHP 변수에서 공백 공간을 제거하는 방법은 무엇입니까? (0) | 2023.02.04 |