Java : FileLock con ejemplos

FileLock (Java SE 22 & JDK 22) en Java con ejemplos.
Encontrará ejemplos de código en la mayoría de los métodos de FileLock.

Nota :


Summary

Un token que representa un bloqueo en una región de un archivo. (Traducción automática)

Class diagram

Note :

  • This file-locking API is platform dependent. Please check the API specification for details.
  • The code examples in this article are running on Windows 10.

An example with the FileChannel.lock method.

public class Child {
    public static void main(String[] args) throws IOException, InterruptedException {
        final var pid = ProcessHandle.current().pid();
        System.out.println("  child : start (pid=" + pid + ")");

        TimeUnit.SECONDS.sleep(1);

        final var file = Path.of("lock.txt");
        try (final var fc = FileChannel.open(
                file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {

            System.out.println("  child : lock start (pid=" + pid + ")");
            try (final var _ = fc.lock()) {
                TimeUnit.MILLISECONDS.sleep(100);

                System.out.println("  child :   *** lock OK! *** (pid=" + pid + ")");
                System.out.println("  child :   sleep 5 seconds ... (pid=" + pid + ")");
                TimeUnit.SECONDS.sleep(5);
            }

            System.out.println("  child : lock end (pid=" + pid + ")");
        }

        System.out.println("  child : end (pid=" + pid + ")");
    }
}
public class Main {
    public static void main(String[] args) throws IOException, InterruptedException {
        System.out.println("main : start");

        // Starts two processes.
        final var builder = new ProcessBuilder("java", "Child").inheritIO();
        final var p1 = builder.start();
        final var p2 = builder.start();

        p1.waitFor();
        p2.waitFor();

        System.out.println("main : end");
    }
}

// Result
// ↓
//> java Main
//main : start
//  child : start (pid=2636)
//  child : start (pid=10564)
//  child : lock start (pid=2636)
//  child : lock start (pid=10564)
//  child :   *** lock OK! *** (pid=2636)
//  child :   sleep 5 seconds ... (pid=2636)
//  child : lock end (pid=2636)
//  child : end (pid=2636)
//  child :   *** lock OK! *** (pid=10564)
//  child :   sleep 5 seconds ... (pid=10564)
//  child : lock end (pid=10564)
//  child : end (pid=10564)
//main : end

An example with the FileChannel.tryLock method.

public class Child {
    public static void main(String[] args) throws IOException, InterruptedException {
        final var pid = ProcessHandle.current().pid();
        System.out.println("  child : start (pid=" + pid + ")");

        TimeUnit.SECONDS.sleep(1);

        final var file = Path.of("lock.txt");
        try (final var fc = FileChannel.open(
                file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {

            System.out.println("  child : lock start (pid=" + pid + ")");

            while (true) {
                try (final var lock = fc.tryLock()) {
                    if (lock != null) {
                        System.out.println("  child :   *** lock OK! *** (pid=" + pid + ")");
                        System.out.println("  child :   sleep 5 seconds ... (pid=" + pid + ")");
                        TimeUnit.SECONDS.sleep(5);
                        break;
                    } else {
                        System.out.println("  child :   *** lock NG! *** (pid=" + pid + ")");
                        System.out.println("  child :   sleep 1 second ... (pid=" + pid + ")");
                        TimeUnit.SECONDS.sleep(1);
                    }
                }
            }

            System.out.println("  child : lock end (pid=" + pid + ")");
        }

        System.out.println("  child : end (pid=" + pid + ")");
    }
}
public class Main {
    public static void main(String[] args) throws IOException, InterruptedException {
        System.out.println("main : start");

        // Starts two processes.
        final var builder = new ProcessBuilder("java", "Child").inheritIO();
        final var p1 = builder.start();
        final var p2 = builder.start();

        p1.waitFor();
        p2.waitFor();

        System.out.println("main : end");
    }
}

// Result
// ↓
//> java Main
//main : start
//  child : start (pid=4392)
//  child : start (pid=748)
//  child : lock start (pid=4392)
//  child :   *** lock OK! *** (pid=4392)
//  child :   sleep 5 seconds ... (pid=4392)
//  child : lock start (pid=748)
//  child :   *** lock NG! *** (pid=748)
//  child :   sleep 1 second ... (pid=748)
//  child :   *** lock NG! *** (pid=748)
//  child :   sleep 1 second ... (pid=748)
//  child :   *** lock NG! *** (pid=748)
//  child :   sleep 1 second ... (pid=748)
//  child :   *** lock NG! *** (pid=748)
//  child :   sleep 1 second ... (pid=748)
//  child :   *** lock NG! *** (pid=748)
//  child :   sleep 1 second ... (pid=748)
//  child : lock end (pid=4392)
//  child : end (pid=4392)
//  child :   *** lock OK! *** (pid=748)
//  child :   sleep 5 seconds ... (pid=748)
//  child : lock end (pid=748)
//  child : end (pid=748)
//main : end

Constructors

FileLock (AsynchronousFileChannel channel, long position, long size, boolean shared)

Inicializa una nueva instancia de esta clase. (Traducción automática)

protected. I think it's rare to create a subclass of this class. Therefore, the code example is omitted.

FileLock (FileChannel channel, long position, long size, boolean shared)

Inicializa una nueva instancia de esta clase. (Traducción automática)

protected. I think it's rare to create a subclass of this class. Therefore, the code example is omitted.

Methods

Channel acquiredBy ()

Devuelve el canal en cuyo archivo se adquirió este bloqueo. (Traducción automática)

final var file = Path.of("R:", "java-work", "lock.txt");
try (final var fc = FileChannel.open(
        file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
    try (final var lock = fc.lock()) {
        final var ret = lock.acquiredBy();
        System.out.println(fc == ret); // true
    }
}

final FileChannel channel ()

Devuelve el canal de archivo en cuyo archivo se adquirió este bloqueo. (Traducción automática)

final var file = Path.of("R:", "java-work", "lock.txt");
try (final var fc = FileChannel.open(
        file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
    try (final var lock = fc.lock()) {
        final var ret = lock.channel();
        System.out.println(fc == ret); // true
    }
}

final void close ()

Este método invoca el método release(). (Traducción automática)

final var file = Path.of("R:", "java-work", "lock.txt");
try (final var fc = FileChannel.open(
        file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
    try (final var lock = fc.lock()) {
        System.out.println(lock.isValid()); // true
    }
}
// An example without a try-with-resources statement.
final var file = Path.of("R:", "java-work", "lock.txt");
try (final var fc = FileChannel.open(
        file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
    final var lock = fc.lock();
    try {
        System.out.println(lock.isValid()); // true
    } finally {
        lock.close();
    }

    System.out.println(lock.isValid()); // false
}

final boolean isShared ()

Indica si este bloqueo es compartido. (Traducción automática)

public class Child {
    public static void main(String[] args) throws IOException, InterruptedException {
        if (args.length != 2) {
            throw new IllegalArgumentException();
        }
        final var type = args[0];
        final var shared = "shared".equals(args[1]);

        println(type, "start");

        TimeUnit.SECONDS.sleep(1);

        final var file = Path.of("lock.txt");
        try (final var fc = FileChannel.open(file,
                StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.READ)) {

            println(type, "tryLock shared = " + shared);
            try (final var lock = fc.tryLock(0, Long.MAX_VALUE, shared)) {
                if (lock != null) {
                    println(type, "  *** lock OK! ***");

                    final var ret = lock.isShared();
                    println(type, "  isShared = " + ret);

                    TimeUnit.SECONDS.sleep(5);
                } else {
                    println(type, "  *** lock NG! ***");
                }
            }
        }
    }

    private static void println(String type, String text) {
        System.out.printf("  child %s : %s%n", type, text);
    }
}
public class Main {
    public static void main(String[] args) throws IOException, InterruptedException {
        if (args.length != 2) {
            throw new IllegalArgumentException();
        }

        System.out.println("main : start");

        final var sharedA = args[0];
        final var sharedB = args[1];

        System.out.println("main : child A = " + sharedA);
        System.out.println("main : child B = " + sharedB);

        // Starts two processes.
        final var p1 = new ProcessBuilder("java", "Child", "A", sharedA).inheritIO().start();
        final var p2 = new ProcessBuilder("java", "Child", "B", sharedB).inheritIO().start();

        p1.waitFor();
        p2.waitFor();

        System.out.println("main : end");
    }
}

// Result
// ↓
//> java Main shared shared
//main : start
//main : child A = shared
//main : child B = shared
//  child A : start
//  child B : start
//  child A : tryLock shared = true
//  child A :   *** lock OK! ***
//  child A :   isShared = true
//  child B : tryLock shared = true
//  child B :   *** lock OK! ***
//  child B :   isShared = true
//main : end
//
//> java Main exclusive shared
//main : start
//main : child A = exclusive
//main : child B = shared
//  child A : start
//  child B : start
//  child A : tryLock shared = false
//  child A :   *** lock OK! ***
//  child A :   isShared = false
//  child B : tryLock shared = true
//  child B :   *** lock NG! ***
//main : end
//
//> java Main shared exclusive
//main : start
//main : child A = shared
//main : child B = exclusive
//  child A : start
//  child B : start
//  child A : tryLock shared = true
//  child A :   *** lock OK! ***
//  child A :   isShared = true
//  child B : tryLock shared = false
//  child B :   *** lock NG! ***
//main : end
//
//> java Main exclusive exclusive
//main : start
//main : child A = exclusive
//main : child B = exclusive
//  child A : start
//  child B : start
//  child A : tryLock shared = false
//  child A :   *** lock OK! ***
//  child A :   isShared = false
//  child B : tryLock shared = false
//  child B :   *** lock NG! ***
//main : end

abstract boolean isValid ()

Indica si este bloqueo es válido o no. (Traducción automática)

final var file = Path.of("R:", "java-work", "lock.txt");
try (final var fc = FileChannel.open(
        file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
    try (final var lock = fc.lock()) {
        System.out.println(lock.isValid()); // true
    }
}
// An example without a try-with-resources statement.
final var file = Path.of("R:", "java-work", "lock.txt");
try (final var fc = FileChannel.open(
        file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
    final var lock = fc.lock();
    try {
        System.out.println(lock.isValid()); // true
    } finally {
        lock.close();
    }

    System.out.println(lock.isValid()); // false
}

final boolean overlaps (long position, long size)

Indica si este bloqueo se superpone o no al rango de bloqueo dado. (Traducción automática)

final var file = Path.of("R:", "java-work", "lock.txt");
try (final var fc = FileChannel.open(
        file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
    try (final var lock = fc.lock(100, 200, false)) {

        System.out.println(lock.position()); // 100
        System.out.println(lock.size()); // 200

        System.out.println(lock.overlaps(0, 99)); // false
        System.out.println(lock.overlaps(0, 100)); // false
        System.out.println(lock.overlaps(0, 101)); // true

        System.out.println(lock.overlaps(99, 1)); // false
        System.out.println(lock.overlaps(100, 1)); // true
        System.out.println(lock.overlaps(101, 1)); // true

        System.out.println(lock.overlaps(299, 1)); // true
        System.out.println(lock.overlaps(300, 1)); // false
        System.out.println(lock.overlaps(301, 1)); // false

        System.out.println(lock.overlaps(0, Long.MAX_VALUE)); // true
    }
}

final long position ()

Devuelve la posición dentro del archivo del primer byte de la región bloqueada. (Traducción automática)

public class Child {
    public static void main(String[] args) throws IOException, InterruptedException {
        if (args.length != 3) {
            throw new IllegalArgumentException();
        }
        final var type = args[0];
        final var position = Long.parseLong(args[1]);
        final var size = Integer.parseInt(args[2]);

        println(type, "start");

        TimeUnit.SECONDS.sleep(1);

        final var file = Path.of("lock.txt");
        try (final var fc = FileChannel.open(file,
                StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.READ)) {

            println(type, "tryLock position = %d size = %d".formatted(position, size));
            try (final var lock = fc.tryLock(position, size, false)) {
                if (lock != null) {
                    println(type, "  *** lock OK! ***");
                    println(type, "  position = " + lock.position());
                    println(type, "  size = " + lock.size());

                    fc.position(position);
                    final var buff = ByteBuffer.allocate(size);
                    fc.read(buff);
                    println(type, "  read = " + Arrays.toString(buff.array()));

                    TimeUnit.SECONDS.sleep(5);
                } else {
                    println(type, "  *** lock NG! ***");
                }
            }
        }

        println(type, "end");
    }

    private static void println(String type, String text) {
        System.out.printf("  child %s : %s%n", type, text);
    }
}
public class Main {
    public static void main(String[] args) throws IOException, InterruptedException {
        if (args.length != 4) {
            throw new IllegalArgumentException();
        }

        System.out.println("main : start");

        final var positionA = args[0];
        final var sizeA = args[1];

        final var positionB = args[2];
        final var sizeB = args[3];

        System.out.println("main : child A position = " + positionA + " size = " + sizeA);
        System.out.println("main : child B position = " + positionB + " size = " + sizeB);

        // Writes 7 bytes of data.
        final var file = Path.of("lock.txt");
        final byte[] bytes = {10, 20, 30, 40, 50, 60, 70};
        Files.write(file, bytes);

        // Starts two processes.
        final var b1 = new ProcessBuilder("java", "Child", "A", positionA, sizeA).inheritIO();
        final var b2 = new ProcessBuilder("java", "Child", "B", positionB, sizeB).inheritIO();

        final var p1 = b1.start();
        TimeUnit.SECONDS.sleep(1);
        final var p2 = b2.start();

        p1.waitFor();
        p2.waitFor();

        System.out.println("main : end");
    }
}

// Result
// ↓
//> java Main 0 7 0 7
//main : start
//main : child A position = 0 size = 7
//main : child B position = 0 size = 7
//  child A : start
//  child B : start
//  child A : tryLock position = 0 size = 7
//  child A :   *** lock OK! ***
//  child A :   position = 0
//  child A :   size = 7
//  child A :   read = [10, 20, 30, 40, 50, 60, 70]
//  child B : tryLock position = 0 size = 7
//  child B :   *** lock NG! ***
//  child B : end
//  child A : end
//main : end
//
//> java Main 0 3 3 4
//main : start
//main : child A position = 0 size = 3
//main : child B position = 3 size = 4
//  child A : start
//  child B : start
//  child A : tryLock position = 0 size = 3
//  child A :   *** lock OK! ***
//  child A :   position = 0
//  child A :   size = 3
//  child A :   read = [10, 20, 30]
//  child B : tryLock position = 3 size = 4
//  child B :   *** lock OK! ***
//  child B :   position = 3
//  child B :   size = 4
//  child B :   read = [40, 50, 60, 70]
//  child A : end
//  child B : end
//main : end

abstract void release ()

Libera este bloqueo. (Traducción automática)

Please see also : close()

final var file = Path.of("R:", "java-work", "lock.txt");
try (final var fc = FileChannel.open(
        file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
    final var lock = fc.lock();
    try {
        System.out.println(lock.isValid()); // true
    } finally {
        lock.release();
    }

    System.out.println(lock.isValid()); // false
}

final long size ()

Devuelve el tamaño de la región bloqueada en bytes. (Traducción automática)

public class Child {
    public static void main(String[] args) throws IOException, InterruptedException {
        if (args.length != 3) {
            throw new IllegalArgumentException();
        }
        final var type = args[0];
        final var position = Long.parseLong(args[1]);
        final var size = Integer.parseInt(args[2]);

        println(type, "start");

        TimeUnit.SECONDS.sleep(1);

        final var file = Path.of("lock.txt");
        try (final var fc = FileChannel.open(file,
                StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.READ)) {

            println(type, "tryLock position = %d size = %d".formatted(position, size));
            try (final var lock = fc.tryLock(position, size, false)) {
                if (lock != null) {
                    println(type, "  *** lock OK! ***");
                    println(type, "  position = " + lock.position());
                    println(type, "  size = " + lock.size());

                    fc.position(position);
                    final var buff = ByteBuffer.allocate(size);
                    fc.read(buff);
                    println(type, "  read = " + Arrays.toString(buff.array()));

                    TimeUnit.SECONDS.sleep(5);
                } else {
                    println(type, "  *** lock NG! ***");
                }
            }
        }

        println(type, "end");
    }

    private static void println(String type, String text) {
        System.out.printf("  child %s : %s%n", type, text);
    }
}
public class Main {
    public static void main(String[] args) throws IOException, InterruptedException {
        if (args.length != 4) {
            throw new IllegalArgumentException();
        }

        System.out.println("main : start");

        final var positionA = args[0];
        final var sizeA = args[1];

        final var positionB = args[2];
        final var sizeB = args[3];

        System.out.println("main : child A position = " + positionA + " size = " + sizeA);
        System.out.println("main : child B position = " + positionB + " size = " + sizeB);

        // Writes 7 bytes of data.
        final var file = Path.of("lock.txt");
        final byte[] bytes = {10, 20, 30, 40, 50, 60, 70};
        Files.write(file, bytes);

        // Starts two processes.
        final var b1 = new ProcessBuilder("java", "Child", "A", positionA, sizeA).inheritIO();
        final var b2 = new ProcessBuilder("java", "Child", "B", positionB, sizeB).inheritIO();

        final var p1 = b1.start();
        TimeUnit.SECONDS.sleep(1);
        final var p2 = b2.start();

        p1.waitFor();
        p2.waitFor();

        System.out.println("main : end");
    }
}

// Result
// ↓
//> java Main 0 7 0 7
//main : start
//main : child A position = 0 size = 7
//main : child B position = 0 size = 7
//  child A : start
//  child B : start
//  child A : tryLock position = 0 size = 7
//  child A :   *** lock OK! ***
//  child A :   position = 0
//  child A :   size = 7
//  child A :   read = [10, 20, 30, 40, 50, 60, 70]
//  child B : tryLock position = 0 size = 7
//  child B :   *** lock NG! ***
//  child B : end
//  child A : end
//main : end
//
//> java Main 0 3 3 4
//main : start
//main : child A position = 0 size = 3
//main : child B position = 3 size = 4
//  child A : start
//  child B : start
//  child A : tryLock position = 0 size = 3
//  child A :   *** lock OK! ***
//  child A :   position = 0
//  child A :   size = 3
//  child A :   read = [10, 20, 30]
//  child B : tryLock position = 3 size = 4
//  child B :   *** lock OK! ***
//  child B :   position = 3
//  child B :   size = 4
//  child B :   read = [40, 50, 60, 70]
//  child A : end
//  child B : end
//main : end

final String toString ()

Devuelve una cadena que describe el rango, el tipo y la validez de este bloqueo. (Traducción automática)

final var file = Path.of("R:", "java-work", "lock.txt");
try (final var fc = FileChannel.open(file, StandardOpenOption.CREATE,
        StandardOpenOption.WRITE, StandardOpenOption.READ)) {

    try (final var lock = fc.lock()) {
        final var str = lock.toString();

        // sun.nio.ch.FileLockImpl[0:9223372036854775807 exclusive valid]
        System.out.println(str);
    }

    try (final var lock = fc.lock(100, 200, true)) {
        final var str = lock.toString();

        // sun.nio.ch.FileLockImpl[100:200 shared valid]
        System.out.println(str);
    }
}

Related posts

To top of page