Path: blob/master/src/java.base/share/classes/java/nio/channels/FileLock.java
41159 views
/*1* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.nio.channels;2627import java.io.IOException;28import java.util.Objects;2930/**31* A token representing a lock on a region of a file.32*33* <p> A file-lock object is created each time a lock is acquired on a file via34* one of the {@link FileChannel#lock(long,long,boolean) lock} or {@link35* FileChannel#tryLock(long,long,boolean) tryLock} methods of the36* {@link FileChannel} class, or the {@link37* AsynchronousFileChannel#lock(long,long,boolean,Object,CompletionHandler) lock}38* or {@link AsynchronousFileChannel#tryLock(long,long,boolean) tryLock}39* methods of the {@link AsynchronousFileChannel} class.40*41* <p> A file-lock object is initially valid. It remains valid until the lock42* is released by invoking the {@link #release release} method, by closing the43* channel that was used to acquire it, or by the termination of the Java44* virtual machine, whichever comes first. The validity of a lock may be45* tested by invoking its {@link #isValid isValid} method.46*47* <p> A file lock is either <i>exclusive</i> or <i>shared</i>. A shared lock48* prevents other concurrently-running programs from acquiring an overlapping49* exclusive lock, but does allow them to acquire overlapping shared locks. An50* exclusive lock prevents other programs from acquiring an overlapping lock of51* either type. Once it is released, a lock has no further effect on the locks52* that may be acquired by other programs.53*54* <p> Whether a lock is exclusive or shared may be determined by invoking its55* {@link #isShared isShared} method. Some platforms do not support shared56* locks, in which case a request for a shared lock is automatically converted57* into a request for an exclusive lock.58*59* <p> The locks held on a particular file by a single Java virtual machine do60* not overlap. The {@link #overlaps overlaps} method may be used to test61* whether a candidate lock range overlaps an existing lock.62*63* <p> A file-lock object records the file channel upon whose file the lock is64* held, the type and validity of the lock, and the position and size of the65* locked region. Only the validity of a lock is subject to change over time;66* all other aspects of a lock's state are immutable.67*68* <p> File locks are held on behalf of the entire Java virtual machine.69* They are not suitable for controlling access to a file by multiple70* threads within the same virtual machine.71*72* <p> File-lock objects are safe for use by multiple concurrent threads.73*74*75* <a id="pdep"></a><h2> Platform dependencies </h2>76*77* <p> This file-locking API is intended to map directly to the native locking78* facility of the underlying operating system. Thus the locks held on a file79* should be visible to all programs that have access to the file, regardless80* of the language in which those programs are written.81*82* <p> Whether or not a lock actually prevents another program from accessing83* the content of the locked region is system-dependent and therefore84* unspecified. The native file-locking facilities of some systems are merely85* <i>advisory</i>, meaning that programs must cooperatively observe a known86* locking protocol in order to guarantee data integrity. On other systems87* native file locks are <i>mandatory</i>, meaning that if one program locks a88* region of a file then other programs are actually prevented from accessing89* that region in a way that would violate the lock. On yet other systems,90* whether native file locks are advisory or mandatory is configurable on a91* per-file basis. To ensure consistent and correct behavior across platforms,92* it is strongly recommended that the locks provided by this API be used as if93* they were advisory locks.94*95* <p> On some systems, acquiring a mandatory lock on a region of a file96* prevents that region from being {@link java.nio.channels.FileChannel#map97* <i>mapped into memory</i>}, and vice versa. Programs that combine98* locking and mapping should be prepared for this combination to fail.99*100* <p> On some systems, closing a channel releases all locks held by the Java101* virtual machine on the underlying file regardless of whether the locks were102* acquired via that channel or via another channel open on the same file. It103* is strongly recommended that, within a program, a unique channel be used to104* acquire all locks on any given file.105*106* <p> Some network filesystems permit file locking to be used with107* memory-mapped files only when the locked regions are page-aligned and a108* whole multiple of the underlying hardware's page size. Some network109* filesystems do not implement file locks on regions that extend past a110* certain position, often 2<sup>30</sup> or 2<sup>31</sup>. In general, great111* care should be taken when locking files that reside on network filesystems.112*113*114* @author Mark Reinhold115* @author JSR-51 Expert Group116* @since 1.4117*/118119public abstract class FileLock implements AutoCloseable {120121private final Channel channel;122private final long position;123private final long size;124private final boolean shared;125126/**127* Initializes a new instance of this class.128*129* @param channel130* The file channel upon whose file this lock is held131*132* @param position133* The position within the file at which the locked region starts;134* must be non-negative135*136* @param size137* The size of the locked region; must be non-negative, and the sum138* {@code position} + {@code size} must be non-negative139*140* @param shared141* {@code true} if this lock is shared,142* {@code false} if it is exclusive143*144* @throws IllegalArgumentException145* If the preconditions on the parameters do not hold146*/147protected FileLock(FileChannel channel,148long position, long size, boolean shared)149{150Objects.requireNonNull(channel, "Null channel");151if (position < 0)152throw new IllegalArgumentException("Negative position");153if (size < 0)154throw new IllegalArgumentException("Negative size");155if (position + size < 0)156throw new IllegalArgumentException("Negative position + size");157this.channel = channel;158this.position = position;159this.size = size;160this.shared = shared;161}162163/**164* Initializes a new instance of this class.165*166* @param channel167* The channel upon whose file this lock is held168*169* @param position170* The position within the file at which the locked region starts;171* must be non-negative172*173* @param size174* The size of the locked region; must be non-negative, and the sum175* {@code position} + {@code size} must be non-negative176*177* @param shared178* {@code true} if this lock is shared,179* {@code false} if it is exclusive180*181* @throws IllegalArgumentException182* If the preconditions on the parameters do not hold183*184* @since 1.7185*/186protected FileLock(AsynchronousFileChannel channel,187long position, long size, boolean shared)188{189Objects.requireNonNull(channel, "Null channel");190if (position < 0)191throw new IllegalArgumentException("Negative position");192if (size < 0)193throw new IllegalArgumentException("Negative size");194if (position + size < 0)195throw new IllegalArgumentException("Negative position + size");196this.channel = channel;197this.position = position;198this.size = size;199this.shared = shared;200}201202/**203* Returns the file channel upon whose file this lock was acquired.204*205* <p> This method has been superseded by the {@link #acquiredBy acquiredBy}206* method.207*208* @return The file channel, or {@code null} if the file lock was not209* acquired by a file channel.210*/211public final FileChannel channel() {212return (channel instanceof FileChannel) ? (FileChannel)channel : null;213}214215/**216* Returns the channel upon whose file this lock was acquired.217*218* @return The channel upon whose file this lock was acquired.219*220* @since 1.7221*/222public Channel acquiredBy() {223return channel;224}225226/**227* Returns the position within the file of the first byte of the locked228* region.229*230* <p> A locked region need not be contained within, or even overlap, the231* actual underlying file, so the value returned by this method may exceed232* the file's current size. </p>233*234* @return The position235*/236public final long position() {237return position;238}239240/**241* Returns the size of the locked region in bytes.242*243* <p> A locked region need not be contained within, or even overlap, the244* actual underlying file, so the value returned by this method may exceed245* the file's current size. </p>246*247* @return The size of the locked region248*/249public final long size() {250return size;251}252253/**254* Tells whether this lock is shared.255*256* @return {@code true} if lock is shared,257* {@code false} if it is exclusive258*/259public final boolean isShared() {260return shared;261}262263/**264* Tells whether or not this lock overlaps the given lock range.265*266* @param position267* The starting position of the lock range268* @param size269* The size of the lock range270*271* @return {@code true} if, and only if, this lock and the given lock272* range overlap by at least one byte273*/274public final boolean overlaps(long position, long size) {275if (position + size <= this.position)276return false; // That is below this277if (this.position + this.size <= position)278return false; // This is below that279return true;280}281282/**283* Tells whether or not this lock is valid.284*285* <p> A lock object remains valid until it is released or the associated286* file channel is closed, whichever comes first. </p>287*288* @return {@code true} if, and only if, this lock is valid289*/290public abstract boolean isValid();291292/**293* Releases this lock.294*295* <p> If this lock object is valid then invoking this method releases the296* lock and renders the object invalid. If this lock object is invalid297* then invoking this method has no effect. </p>298*299* @throws ClosedChannelException300* If the channel that was used to acquire this lock301* is no longer open302*303* @throws IOException304* If an I/O error occurs305*/306public abstract void release() throws IOException;307308/**309* This method invokes the {@link #release} method. It was added310* to the class so that it could be used in conjunction with the311* automatic resource management block construct.312*313* @since 1.7314*/315public final void close() throws IOException {316release();317}318319/**320* Returns a string describing the range, type, and validity of this lock.321*322* @return A descriptive string323*/324public final String toString() {325return (this.getClass().getName()326+ "[" + position327+ ":" + size328+ " " + (shared ? "shared" : "exclusive")329+ " " + (isValid() ? "valid" : "invalid")330+ "]");331}332333}334335336