简体   繁体   English

如何从终结器(资源对象)抛出异常

[英]How to throw throw from finalizers(of resource objects)

Finalizers are not destructors, finalizers are useless. 终结器不是析构函数,终结器没有用。

From what I hear a lot of Java resource Objects dispose on finalize() "just in case". 从我听到的内容中,很多Java资源对象都以“以防万一”的形式放在finalize()上。
This seems an overly permissive attitude likely to lead to bugs. 这似乎是一种过分放纵的态度,很可能导致错误。

The least you would want to do is for finalize to log errors(un disposed resources at finalization time) and print them to standard out and then dispose. 您最不希望做的是终结处理,以记录错误(在终结处理时未处理的资源)并将其打印为标准输出,然后进行处理。
A more restrictive attitude might be to thow an exception instead. 更具限制性的态度可能是抛出异常。 I'm not necessarily going to implement such restrictive resource objects but I'd like to know how to do it. 我不一定要实现这种限制性资源对象,但我想知道如何去做。

But in Java an exception thrown in a finalizer gets ignored(other then the object being put back on the list to be finalized again). 但是在Java中,终结器中引发的异常将被忽略(否则,该对象将被放回到列表中以再次终结)。 Is there a way to implement something like this? 有没有办法实现这样的事情? Maybe a way to give thread that created object an exception from the finalizer if it still exists(or possibly parent threads if not? 也许一种方法可以给创建对象的线程提供终结器的终结器(如果它仍然存在)(或者如果不存在则可以是父线程)?

Also!!!!! 也!!!!! How do other gc languages(especially C#,python and the like) deal with resource finalization(do they generally implement "just in case disposal" for resource classes?), throwing from finalizers, giving exeptions to other threads. 其他gc语言(尤其是C#,python等)如何处理资源终结处理(它们通常对资源类实现“以防万一的处置”吗?),从终结处理程序抛出,为其他线程提供实例。 (note: I don't care much about with/using sugar for calling dispose method or methods accepting closures that automatically close resource, I'm intrested in what role finalizers play and error propagation from finalizers). (注意:我不太在意/使用糖来调用dispose方法或接受自动关闭资源的闭包的方法,我对终结器扮演什么角色以及终结器的错误传播很感兴趣)。

The finaliser is called in a dedicated thread so throwing an exception or error wouldn't achieve anything because you wouldn't be able to catch the exception in your code or one of your threads. 终结器在专用线程中被调用,因此引发异常或错误不会实现任何效果,因为您将无法在代码或线程之一中捕获异常。

If you want to pass exceptions to another thread you can do this in any number of ways. 如果要将异常传递给另一个线程,则可以采用多种方法来执行此操作。 However its not clear to me what you would do in another thread, that you would do in the current thread. 但是,我不清楚在另一个线程中将要执行的操作,即在当前线程中将要执行的操作。 ie why create an exception to pass to another thread to turn into log message when you could have the current thread log a message. 例如,当您可以让当前线程记录一条消息时,为什么要创建一个异常以传递给另一个线程以变成日志消息。

Finalizers in themselves have loads and loads and loads of disadvantages right from taking longer time for Object creation to not disposing the resources til the finalizer thread calls the finalize method to so on. 终结器本身有很多负担,也有缺点和缺点,从花费更长的时间创建对象到在终结器线程调用finalize方法之前不分配资源等等。

The only reason why one should use it is to take precaution to dispose resources say for example InputStream's have the method which results in close(), now this might never be called also. 一个人使用它的唯一原因是要谨慎处理资源,例如说InputStream拥有导致close()的方法,现在可能永远也不会调用它。 The other case when one must use it is while using native's. 另一种必须使用它的情况是使用本机的。 There is abolutely no other case when one should do it. 绝对没有其他情况可以这样做。

Now the problem with your desire to implement the above is that say: there is an object with a finalize() method. 现在,您希望实现上述问题的问题是:存在一个带有finalize()方法的对象。 Now when there is no strong reference to the object, it is sent for Garbage Collection. 现在,当没有强烈引用该对象时,将其发送给垃圾回收。 Now it checks from its entry table, if this particular object has a finalize() method( which was noted when the object was created at the first place). 现在,它从其条目表中检查该特定对象是否具有finalize()方法(该方法在最初创建该对象时便已注意到)。 Now when the finalizer thread runs the finalize() method, and inside this method there is a block of code which ultimately resulted in this method having a strong reference. 现在,当终结器线程运行finalize()方法时,在该方法内部有一段代码,最终导致该方法具有强大的参考价值。

Next time when the same object is called for garbage collection, this object is not sent to finalizer queue the second time (by default as no object can goto finalizer queue more than once), hence the finalize() method is not called the second time. 下次调用同一对象进行垃圾回收时,该对象不会第二次发送到终结器队列(默认情况下,没有对象可以多次进入终结器队列),因此第二次不调用finalize()方法。 This might result in huge problem. 这可能会导致巨大的问题。

Hence if you are dealing with some thing, make sure you do it outside the finalize() method rather than doing it in finalize() as it only leads to problems and nothing else 因此,如果您要处理某些事情,请确保在finalize()方法之外进行操作,而不要在finalize()中进行操作,因为这样做只会导致问题,而不会导致其他问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM