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

时间:2011-09-24 00:28:00

标签: java multithreading pid

我有一个带有几个线程的应用程序,它们操作数据并将输出保存在特定目录,Linux或Windows机器上的不同临时文件中。最终需要删除这些文件。

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

由于应用程序在JVM的单个实例上运行,我假设它将具有单个进程ID,这将是JVM的进程ID,对吧?

在这种情况下,区分这些文件的唯一方法是将它们保存在一个文件夹中,其名称将与线程ID相关。

这种做法是否合理,或者我应该做些什么呢?

3 个答案:

答案 0 :(得分:2)

java.io.File可以create临时文件给你。只要保留与每个线程关联的文件列表,就可以在线程退出时删除它们。如果线程未完成,您还可以将文件标记为delete on exit

答案 1 :(得分:1)

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

JVM可以很好地为多个Java线程重用底层操作系统线程,因此在Java中退出的线程与操作系统级别发生的类似事件之间没有保证相关性。

如果您只需要清理陈旧文件,按创建时间戳排序文件应该可以完成这项工作吗?无需在临时文件名中对任何特殊内容进行编码。

请注意,PID和TID既不能保证增加,也不能保证在出口中保持唯一。操作系统可以自由回收ID。 (实际上,ID必须在重新使用之前包装,但在某些机器上,只有在创建了32k或64k进程后才会发生。

答案 2 :(得分:1)

这种方法似乎最简单的解决方案是扩展Thread - 从未想过我会在那一天看到它。

作为P.T.已经说过,只要线程处于活动状态,线程ID就是唯一的,它们可以并且肯定会被操作系统重用。

因此,不是这样做,而是使用可以在构造中指定的Thread名称并使其简单,只需编写一个小类:

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,其中一个线程将执行多个作业。目前,你在一个线程中有业务逻辑 - 这并没有让我觉得特别好的设计。