【问题标题】:Directory naming using Process ID and Thread ID使用进程 ID 和线程 ID 的目录命名
【发布时间】:2011-11-24 01:37:46
【问题描述】:

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

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

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

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

这种方法合理吗,还是我应该做点别的?

【问题讨论】:

    标签: java multithreading pid


    【解决方案1】:

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

    JVM 可以很好地为多个 Java 线程重用底层 OS 线程,因此在 Java 中退出的线程与在 OS 级别发生的任何类似情况之间没有保证的相关性。

    如果您只需要清理过时的文件,那么按文件的创建时间戳对文件进行排序就足以完成这项工作吗?不需要在临时文件名中编码任何特殊的东西。

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

    【讨论】:

    • 无法根据时间或任何其他“文件系统”属性进行清理,因为文件是特定于线程的。
    【解决方案2】:

    似乎这种方法最简单的解决方案实际上是扩展 Thread - 没想到我会看到那一天。

    作为 P.T.已经说过线程 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,其中一个线程将完成一项以上的工作。目前,您在线程中有业务逻辑 - 我觉得这并不是特别好的设计。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我知道这些可能性,但应用程序处理大量数据,因此它可能会在线程退出之前用完磁盘空间。
      • 您的程序如何知道何时不再需要每个临时文件?如果存储似乎是问题,您为什么还要担心组织它们?
      • 它对文件进行一些处理,然后可以处理它。我只需要按照我描述的那样将它们组织在目录中,处理它们,然后擦除整个目录。
      • 我还是不明白你为什么要按进程和线程ID来组织你的临时文件。只要您在程序中引用了它们(最好是java.io.File 实例),您就可以非常轻松地删除它们,无论它们是如何组织的。
      • 出于多种原因,包括任何应用程序(或服务器)崩溃并将数据留在磁盘上的可能性。这些将需要稍后清理。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      相关资源
      最近更新 更多