使用进程ID和线程ID进行目录命名
我有一个应用程序,它具有一些处理数据的线程,并将输出保存在Linux或Windows计算机上的特定目录上的不同临时文件中。这些文件最终需要擦除。使用进程ID和线程ID进行目录命名
我想要做的是能够更好地分离文件,所以我想通过进程ID和线程ID来做到这一点。这将有助于应用程序节省磁盘空间,因为在线程终止时,可删除具有该线程文件的整个目录,并使应用程序的其余部分重新使用相应的磁盘空间。
由于应用程序运行在JVM的单个实例上,因此我认为它将有一个进程ID,它将是JVM的进程ID,对吧?
既然如此,区分这些文件的唯一方法就是将它们保存在一个文件夹中,其名称将与线程ID相关。
这种方法是否合理,还是应该做其他事情?
java.io.File可以为您临时存放的文件create。只要您保留与每个线程关联的文件列表,您可以在线程退出时将其删除。如果线程没有完成,您还可以将这些文件标记为delete on exit。
你是对的,JVM有一个进程ID,并且该JVM中的所有线程将共享进程ID。 (JVM可以使用多个进程,但AFAIK,JVM不会这样做)。
JVM可能会很好地为多个Java线程重新使用底层OS线程,所以线程之间没有保证的关联Java中退出以及在操作系统级别发生的任何类似事件。
如果你只是需要清理陈旧的文件,按他们的创建时间戳对文件进行排序应该足够的工作吗?无需在临时文件名中编码任何特别的东西。
请注意,PID和TID既不保证增加,也不保证在出口之间是唯一的。操作系统可以自由地回收一个ID。 (在实践中,ID必须在重用之前环绕,但在某些机器上可能会在仅创建32k或64k进程后发生。
无法基于时间或任何其他“文件系统”属性进行清理,因为这些文件是特定于线程的。 – 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,其中一个线程将执行多个任务。目前你的业务逻辑处于一个线程中 - 这并不会让我成为特别好的设计。
我知道这些可能性,但应用程序处理大量数据,因此在线程退出之前它可能会耗尽磁盘空间。 – PNS
程序如何知道它何时不再需要每个临时文件?如果存储似乎成为问题,为什么要关心组织它们? – CurtisB
它对文件进行一些处理,然后可以处置它。我只需要按照我所述将它们组织到目录中,然后处理它们,然后擦除整个目录。 – PNS