2016-08-30 36 views
9

Kullanıcı eylemleri üzerine bir iletiyi sıçramak için bir zamanlayıcı başlatan bir uygulama var. JDK profilerinde, diğer tüm iş parçacıklarının GC tarafından yürütüldükten sonra kaldırıldığı anlaşılıyor (sanırım) ama oluşturulan zamanlayıcılar kaldırılmıyor. Orada neler olabilir?Java - Zamanlayıcı yürütme sonrasında kaldırılmıyor

benim zamanlayıcı:

/** 
* @param owner 
* @param added 
*/ 
public static void splashParentWithAnimation(AnchorPane owner, Parent added,double posX,double posY) { 
    // addParentWithAnimation(owner, added); 
    owner.getChildren().add(added); 

    AnchorPane.setLeftAnchor(added, posX); 

    AnchorPane.setTopAnchor(added, posY); 

    FadeTransition ft1 = new FadeTransition(Duration.millis(300), added); 
    ft1.setFromValue(0.0); 
    ft1.setToValue(1.0); 
    ft1.play(); 


    Timer messagePrinter = new Timer(); 
    messagePrinter.schedule(new TimerTask() { 

     @Override 
     public void run() { 
      Platform.runLater(() -> { 

       if (!owner.getChildren().contains(added)) 
        return; 

       FadeTransition ft1 = new FadeTransition(Duration.millis(300), added); 
       ft1.setFromValue(1.0); 
       ft1.setToValue(0.0); 
       ft1.play(); 
       ft1.setOnFinished((e) -> { 

        if (owner.getChildren().contains(added)) 
         owner.getChildren().remove(added); 
       }); 

      }); 

     } 
    }, 1000); 
} 

JDK profilci: enter image description here

ben statik yöntemi kullanıyorum yoksa kendim mi yok etmeliyiz çünkü mı?

cevap

7

Aslında, burada zamanlayıcı sonlandırmayla ilgili bir sorununuz yok. Profilcideki gördüğünüz dişler zaten –'u sonlandırmışlar, sol tarafta beyaz bir kutunun olup öldüğünü gösterir.

Profil oluşturucu, iş parçacığı zaten ölü ve çöp toplanmış olsa bile, program yürütme sırasında oluşturulan tüm konuları gösterir.

Aşağıdakileri yaparak bunu kolayca onaylayabilirsiniz: Bir lambda yerine, TimerTask alt sınıfını oluşturun ve bir şey yazdırmak için finalize() yöntemini yeniden tanımlayın. Çöp koleksiyonları gerçekleştirildiğinde, görevlerinizin kesinleştiğini göreceksiniz. Yalnızca iş parçacığı durdurulduğunda gerçekleşebilir, çünkü bu, Runnable (Runnable (TimerTask uygulamarı) referansı bıraktığı tek yerdir.

Bunu onaylamanın bir başka yolu, tablonun üst kısmındaki Görünüm açılır listesinden 'Canlı Konular' seçimini yapmaktır. Ayrıca, daha iyi bir şey için Timer'u değiştirmenizi tavsiye ederim. Bazı görevleri geciktirmeniz gereken her zaman bir iş parçacığı oluşturmak çok israfsız. ScheduledThreadPoolExecutor göz at, çok daha uygun sizin görev için görünüyor: bir kerede çok fazla zamanlanmış görevler var ve bu görevleri yeterince küçük değilse

// Create a shared executor with a single thread 
private final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); 

// Instead of creating a Timer, schedule the task 
executor.schedule(() -> { 
    // Do what you need here 
}, 1, TimeUnit.SECONDS); 

// Don't forget to terminate the scheduler when you don't need it anymore 
scheduler.terminate(); 

Sen uygulamakla birden fazla iş parçacığı ekleyebilirsiniz.

+0

Bu konuda emin değilim ama bilmiyorum, her neyse, javaFX'in zaman çizelgesini (en azından benim için) daha iyi olan yerine kullandım –

2

Bunun için zamanlayıcıyı el ile atmanız gerekir.

java.util.Timer kullanırsanız, kaynakları ücretsiz olarak cancel yöntemini çağırmanız gerekir.

+0

nasıl yapılacağını anlatabilir misiniz? –

+0

name_of_timer.cancel(); ? –

+0

Evet. Bu durumda 'messagePrinter.cancel();' – talex

1

Zamanlayıcınız, daemon olmayan bir iş parçacığıyla oluşturulur; daemon olmayan iş parçacıkları, programınızın sonlandırılmasını engelleyebilir. Zamanlayıcı için yapıcıyı bir daemon iş parçacığı kullanarak yapan kullanmalısınız.

boolean daemon=true; Timer messagePrinter = new Timer(daemon);

Ama Andrew Lygin anlaşılacağı gibi bir ExecutorService kullanarak olacaktır.