동일한 스레드에서 start 메서드를 두 번 호출하는 것이 합법적입니까?
다음 코드는 프로그램에서 메서드를 두 번java.lang.IllegalThreadStateException: Thread already started
호출 할 때 연결됩니다 .start()
updateUI.join();
if (!updateUI.isAlive())
updateUI.start();
이것은 일 두 번째 시간 updateUI.start()
이라고합니다. 나는 그것을 여러 번 밟았고 스레드가 호출되고을 누르기 전에 완전히 실행됩니다 updateUI.start()
.
호출 updateUI.run()
은 오류를 피하지만 스레드가 UI 스레드 (SO의 다른 게시물에서 언급 한 호출 스레드)에서 실행되도록합니다. 이것은 내가 원하는 것이 아닙니다.
스레드 는 한 번만 시작할 수 있습니까 ? 그렇다면 스레드를 다시 실행하려면 어떻게해야합니까? 이 특정 스레드는 UI 스레드에서 수행 한 것보다 스레드에서 수행하지 않고 사용자가 비합리적으로 오래 기다릴 경우 백그라운드에서 계산을 수행합니다.
로부터 자바 API 사양 에 대한 Thread.start
방법 :
스레드를 두 번 이상 시작하는 것은 결코 합법적이지 않습니다. 특히 스레드가 실행을 완료 한 후에는 다시 시작할 수 없습니다.
더욱이:
오류 :
IllegalThreadStateException
-스레드가 이미 시작된 경우.
예, a Thread
는 한 번만 시작할 수 있습니다.
그렇다면 스레드를 다시 실행하려면 어떻게해야합니까?
을 Thread
두 번 이상 실행해야하는 경우의 새 인스턴스를 Thread
만들고 호출 start
해야합니다.
맞습니다. 문서에서 :
스레드를 두 번 이상 시작하는 것은 결코 합법적이지 않습니다. 특히 스레드가 실행을 완료 한 후에는 다시 시작할 수 없습니다.
반복 계산을 위해 무엇을 할 수 있는지에 관해서는 SwingUtilities invokeLater 메소드를 사용할 수있는 것처럼 보입니다 . 이미 run()
직접 호출을 실험하고 있습니다. 즉 Runnable
, raw가 아닌 a 사용에 대해 이미 생각하고 Thread
있습니다. 작업 invokeLater
에만 방법을 사용 해보고 Runnable
그것이 당신의 정신 패턴에 조금 더 잘 맞는지 확인하십시오.
다음은 문서의 예입니다.
Runnable doHelloWorld = new Runnable() {
public void run() {
// Put your UI update computations in here.
// BTW - remember to restrict Swing calls to the AWT Event thread.
System.out.println("Hello World on " + Thread.currentThread());
}
};
SwingUtilities.invokeLater(doHelloWorld);
System.out.println("This might well be displayed before the other message.");
해당 println
호출을 계산으로 대체하면 정확히 필요한 것일 수 있습니다.
편집 : 댓글에 대한 후속 조치로 원본 게시물에서 Android 태그를 발견하지 못했습니다. Android 작업에서 invokeLater에 해당하는 것은 Handler.post(Runnable)
. javadoc에서 :
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* @param r The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
따라서 Android 세계에서는 위와 동일한 예제를 사용하여 Swingutilities.invokeLater
를 Handler
.
방금 도착한 답변은 당신이하는 일을해서는 안되는 이유를 다룹니다. 실제 문제를 해결하기위한 몇 가지 옵션이 있습니다.
이 특정 스레드는 UI 스레드에서 수행 한 것보다 스레드에서 수행하지 않고 사용자가 비합리적으로 오래 기다릴 경우 백그라운드에서 계산을 수행합니다.
자신의 스레드를 덤프하고 AsyncTask
.
또는 필요할 때 새 스레드를 만듭니다.
Or set up your thread to operate off of a work queue (e.g., LinkedBlockingQueue
) rather than restarting the thread.
No, we cannot start Thread again, doing so will throw runtimeException java.lang.IllegalThreadStateException. >
The reason is once run() method is executed by Thread, it goes into dead state.
Let’s take an example- Thinking of starting thread again and calling start() method on it (which internally is going to call run() method) for us is some what like asking dead man to wake up and run. As, after completing his life person goes to dead state.
public class MyClass implements Runnable{
@Override
public void run() {
System.out.println("in run() method, method completed.");
}
public static void main(String[] args) {
MyClass obj=new MyClass();
Thread thread1=new Thread(obj,"Thread-1");
thread1.start();
thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
}
}
/*OUTPUT in run() method, method completed. Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.start(Unknown Source) */
What you should do is create a Runnable and wrap it with a new Thread each time you want to run the Runnable. It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
It is as you said, a thread cannot be started more than once.
Straight from the horse's mouth: Java API Spec
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
If you need to re-run whatever is going on in your thread, you will have to create a new thread and run that.
To re-use a thread is illegal action in Java API. However, you could wrap it into a runnable implement and re-run that instance again.
Yes we can't start already running thread. It will throw IllegalThreadStateException at runtime - if the thread was already started.
What if you really need to Start thread: Option 1 ) If a Thread needs to be run more than once, then one should make an new instance of the Thread and call start on it.
Can a Thread be started only once?
Yes. You can start it exactly once.
If so than what do I do if I want to run the thread again?This particular thread is doing some calculation in the background, if I don't do it in the thread than it's done in the UI thread and the user has an unreasonably long wait.
Don't run the Thread
again. Instead create Runnable and post it on Handler of HandlerThread. You can submit multiple Runnable
objects. If want to send data back to UI Thread, with-in your Runnable
run()
method, post a Message
on Handler
of UI Thread and process handleMessage
Refer to this post for example code:
It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
I have had to fix a resource leak that was caused by a programmer who created a Thread but instead of start()ing it, he called the run()-method directly. So avoid it, unless you really really know what side effects it causes.
'IT박스' 카테고리의 다른 글
ValueError : 닫힌 파일에 대한 I / O 작업 (0) | 2020.09.10 |
---|---|
'instanceof'연산자는 인터페이스와 클래스에 대해 다르게 작동합니다. (0) | 2020.09.10 |
MKAnnotationView의 콜 아웃 풍선을 사용자 정의하는 방법은 무엇입니까? (0) | 2020.09.10 |
try-except 블록과 함께 파이썬 "with"문 사용 (0) | 2020.09.10 |
JSON에서 TypeScript 클래스 인스턴스로? (0) | 2020.09.10 |