使用进程ID和线程ID进行目录命名

问题描述:

我有一个应用程序,它具有一些处理数据的线程,并将输出保存在Linux或Windows计算机上的特定目录上的不同临时文件中。这些文件最终需要擦除。使用进程ID和线程ID进行目录命名

我想要做的是能够更好地分离文件,所以我想通过进程ID和线程ID来做到这一点。这将有助于应用程序节省磁盘空间,因为在线程终止时,可删除具有该线程文件的整个目录,并使应用程序的其余部分重新使用相应的磁盘空间。

由于应用程序运行在JVM的单个实例上,因此我认为它将有一个进程ID,它将是JVM的进程ID,对吧?

既然如此,区分这些文件的唯一方法就是将它们保存在一个文件夹中,其名称将与线程ID相关。

这种方法是否合理,还是应该做其他事情?

java.io.File可以为您临时存放的文件create。只要您保留与每个线程关联的文件列表,您可以在线程退出时将其删除。如果线程没有完成,您还可以将这些文件标记为delete on exit

+0

我知道这些可能性,但应用程序处理大量数据,因此在线程退出之前它可能会耗尽磁盘空间。 – PNS

+0

程序如何知道它何时不再需要每个临时文件?如果存储似乎成为问题,为什么要关心组织它们? – CurtisB

+0

它对文件进行一些处理,然后可以处置它。我只需要按照我所述将它们组织到目录中,然后处理它们,然后擦除整个目录。 – PNS

你是对的,JVM有一个进程ID,并且该JVM中的所有线程将共享进程ID。 (JVM可以使用多个进程,但AFAIK,JVM不会这样做)。

JVM可能会很好地为多个Java线程重新使用底层OS线程,所以线程之间没有保证的关联Java中退出以及在操作系统级别发生的任何类似事件。

如果你只是需要清理陈旧的文件,按他们的创建时间戳对文件进行排序应该足够的工作吗?无需在临时文件名中编码任何特别的东西。

请注意,PID和TID既不保证增加,也不保证在出口之间是唯一的。操作系统可以*地回收一个ID。 (在实践中,ID必须在重用之前环绕,但在某些机器上可能会在仅创建32k或64k进程后发生。

+0

无法基于时间或任何其他“文件系统”属性进行清理,因为这些文件是特定于线程的。 – PNS

看来这种方法的最简单的解决方案实际上是延长线程 - 从不想过我会看到那一天。

正如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,其中一个线程将执行多个任务。目前你的业务逻辑处于一个线程中 - 这并不会让我成为特别好的设计。