2011-09-24 170 views
2

我有一個應用程序,它具有一些處理數據的線程,並將輸出保存在Linux或Windows計算機上的特定目錄上的不同臨時文件中。這些文件最終需要擦除。使用進程ID和線程ID進行目錄命名

我想要做的是能夠更好地分離文件,所以我想通過進程ID和線程ID來做到這一點。這將有助於應用程序節省磁盤空間,因爲在線程終止時,可刪除具有該線程文件的整個目錄,並使應用程序的其餘部分重新使用相應的磁盤空間。

由於應用程序運行在JVM的單個實例上,因此我認爲它將有一個進程ID,它將是JVM的進程ID,對吧?

既然如此,區分這些文件的唯一方法就是將它們保存在一個文件夾中,其名稱將與線程ID相關。

這種方法是否合理,還是應該做其他事情?

回答

2

java.io.File可以爲您臨時存放的文件create。只要您保留與每個線程關聯的文件列表,您可以在線程退出時將其刪除。如果線程沒有完成,您還可以將這些文件標記爲delete on exit

+0

我知道這些可能性,但應用程序處理大量數據,因此在線程退出之前它可能會耗盡磁盤空間。 – PNS

+0

程序如何知道它何時不再需要每個臨時文件?如果存儲似乎成爲問題,爲什麼要關心組織它們? – CurtisB

+0

它對文件進行一些處理,然後可以處置它。我只需要按照我所述將它們組織到目錄中,然後處理它們,然後擦除整個目錄。 – PNS

1

你是對的,JVM有一個進程ID,並且該JVM中的所有線程將共享進程ID。 (JVM可以使用多個進程,但AFAIK,JVM不會這樣做)。

JVM可能會很好地爲多個Java線程重新使用底層OS線程,所以線程之間沒有保證的關聯Java中退出以及在操作系統級別發生的任何類似事件。

如果你只是需要清理陳舊的文件,按他們的創建時間戳對文件進行排序應該足夠的工作嗎?無需在臨時文件名中編碼任何特別的東西。

請注意,PID和TID既不保證增加,也不保證在出口之間是唯一的。操作系統可以自由地回收一個ID。 (在實踐中,ID必須在重用之前環繞,但在某些機器上可能會在僅創建32k或64k進程後發生。

+0

無法基於時間或任何其他「文件系統」屬性進行清理,因爲這些文件是特定於線程的。 – PNS

1

看來這種方法的最簡單的解決方案實際上是延長線程 - 從不想過我會看到那一天。

正如PT已經說過線程ID只唯一隻要線程是活動的,他們可以和大多數肯定會被操作系統重用。

所以不是這樣做的通過這種方式,您可以使用可在施工中指定的螺紋名稱,並使其變得簡單,只需編寫一個小類:

public class MyThread extends Thread { 
    private static long ID = 0; 

    public MyThread(Runnable r) { 
     super(r, getNextName()); 
    } 

    private static synchronized String getNextName() { 
     // We can get rid of synchronized with some AtomicLong and so on, 
     // doubt that's necessary though 
     return "MyThread " + ID++; 
    } 

} 

然後,你可以做這樣的事情:

public static void main(String[] args) throws InterruptedException { 
    Thread t = new MyThread(new Runnable() { 
     @Override 
     public void run() { 
      System.out.println("Name: " + Thread.currentThread().getName()); 
     } 
    }); 
    t.start(); 
} 

您必須覆蓋要使用,並始終使用MyThread類的所有構造函數,但這樣一來就可以保證一個獨特的映射 - 以及至少2^64-1(畢竟,負值也很好),這應該足夠了。

雖然我仍然不認爲這是最好的辦法,可能是更好的創建一個包含所有必要的信息,並能儘快,因爲它是不再需要清理的文件中有一些「工作」類 - 這樣,你也可以輕鬆使用ThreadPools和co,其中一個線程將執行多個任務。目前你的業務邏輯處於一個線程中 - 這並不會讓我成爲特別好的設計。