--- old/src/java.base/share/classes/java/io/DeleteOnExitHook.java 2019-07-10 13:58:16.089546034 +0200 +++ new/src/java.base/share/classes/java/io/DeleteOnExitHook.java 2019-07-10 13:58:15.993546516 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ */ class DeleteOnExitHook { - private static LinkedHashSet files = new LinkedHashSet<>(); + private static LinkedHashMap files = new LinkedHashMap<>(); static { // DeleteOnExitHook must be the last shutdown hook to be invoked. // Application shutdown hooks may add the first file to the @@ -61,18 +61,24 @@ throw new IllegalStateException("Shutdown in progress"); } - files.add(file); + files.computeIfAbsent(file, f -> new int[1])[0]++; + } + + static synchronized void remove(String file) { + if(files != null) { + files.computeIfPresent(file, (f, count) -> --count[0] <= 0 ? null : count); + } } static void runHooks() { - LinkedHashSet theFiles; + LinkedHashMap theFiles; synchronized (DeleteOnExitHook.class) { theFiles = files; files = null; } - ArrayList toBeDeleted = new ArrayList<>(theFiles); + ArrayList toBeDeleted = new ArrayList<>(theFiles.keySet()); // reverse the list to maintain previous jdk deletion order. // Last in first deleted.