假设在我的应用程序中,一个线程正在执行函数说:
public void function(){
.
.
.
try{
//do something
}catch(Exception ex){
throw ex;
}
}
现在每次线程执行该函数时,它会进入catch块然后抛出异常ex,甚至parent函数也会向其父级抛出异常。 现在问题是我的线程会死,否则会导致mu应用中的线程泄漏?
答案 0 :(得分:1)
线程将正常终止 ,但问题是它不会释放发生异常时所持有的任何资源。
示例:
public class TryThreads {
static void someMethod() throws Exception {
System.out.println("hello");
throw new Exception();
}
public static void main(String[] args) throws InterruptedException {
Thread T = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getState());
try {
someMethod();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("still here");
}
});
T.start();
Thread.currentThread().sleep(1000);
System.out.println(T.getState());
}
}
O / P:
RUNNABLE
hello
java.lang.Exception
at TryThreads.someMethod(TryThreads.java:4)
at TryThreads$1.run(TryThreads.java:15)
at java.lang.Thread.run(Unknown Source)
still here
**TERMINATED** --> this line
答案 1 :(得分:0)
用户代码未被捕获的异常最终将被线程的run()函数抛出。这会导致线程终止执行。
答案 2 :(得分:0)
在Java中,Thread受垃圾回收的影响。不需要(或方式)手动释放(内部)资源。
只有在累积对线程的引用并且永远不会释放它们时,才会创建线程泄漏。这意味着:
// cool, nobody references the thread, let the gc collect it when done
void foo() {
Thread t = new Thread(new Runnable { ... });
t.start();
}
// not cool, maybe set "t = null" some time
private Thread t = new Thread(new Runnable { ... });
void foo() {
t.start();
}
还要注意,我没有理由认为JVM一旦完成其目的就应该保留java.lang.Thread的内部资源(例如pthread_t)。所以一般来说,除了JMM之外你没有什么特别需要担心的,并且首先手动管理一个线程。你为什么不使用ExecutorService?
答案 3 :(得分:0)
VM为每个非守护程序线程在内存中保存一个线程控制块(一个小数据结构)。这通常不会被删除,直到另一个线程“加入”该线程(即对它发出join()调用以获得终止状态,该状态在该控制块中保存)。如果您的代码没有通过加入线程来清理这些控制块,那么从技术上讲,您有资源泄漏。如果VM具有有限数量的控制块,您最终可以全部使用它们。
通常的解决方案是在启动它们之前创建线程守护程序。这基本上告诉VM您对终止状态不感兴趣,并且不需要通过调用join()来与线程的终止同步,并且当它们终止时,VM将为您清理控制块。