我有一个javafx应用程序,我使用
在FX线程中调用阻塞方法new Thread(() -> doWork(someParam)).start();
我希望用户能够单击调用方法的按钮,但不会冻结UI。我还希望点击次数等于方法调用次数。
这目前解决了我的问题,但这会导致有关内存使用的任何问题吗?我理解线程最终会死掉,垃圾收集器会对它采取行动,但这是不好的做法吗?
同样,当创建新线程时,会为其分配新增加的线程ID。 线程ID溢出时会出现问题吗?
答案 0 :(得分:3)
创建线程非常昂贵。你应该使用某种线程池。 Executors
类提供了方便的方法。
例如,您可以这样做:
private final ExecutorService exec = Executors.newCachedThreadPool();
然后
exec.submit(() -> doWork(someParam));
还有一些方法可以创建固定大小(Executors.newFixedThreadPool(n)
)的线程池,并且这些方法都是重载的,因此您可以定义创建线程时如何创建线程。例如,如果你想要一个缓存的线程池,但希望线程是守护程序线程(这样他们就不会阻止应用程序退出),你可以这样做
private final ExecutorService exec = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t ;
});
另请注意,在应用程序关闭时,您应该关闭线程池:
exec.shutdown();
据我所知,溢出线程ID不会导致问题;线程ID是long
,因此很难达到溢出,即使你这样做也只会换成一个大的负数。然而,通常更好的做法是使用此处概述的线程池,这无论如何都会使这个问题没有实际意义。