Create a Lock Server
If an implementationwhether the operating system or the Java implementationdoes not provide system-wide lock safety, it's because that implementation does not have a central facility for managing locks for the entire system. In a sense, each process is left to coordinate locking activities on it's own (see Figure 2
To remedy this, you can create your own central facility: a lock server. Every program that uses locks will connect to and request locks from the lock server. The server will handle the locking logic that the underlying system does not provide. All lock and release requests must go through this central server. Figure 3 shows the lock server structure.
The lock server uses the implementation that the underlying system provides to implement the locking logic. All locking activity goes through this central facility. In this case, process-wide locking is sufficient because only one process actually is doing any lockingthe lock server itself.
The Lock Server's Required Classes
The lock server implementation I describe will use the following classes:
- LockServer.java. This is the central server that provides lock services to other processes. It listens for incoming connections on a specified port and responds to lock and release requests from the clients at the other end of those connections.
- RemoteLockClient.java. A program uses this class on the client side to make use of the locking services a lock server provides. This object establishes a connection to the server and handles the details of communicating with the server.
- RemoteLock.java. This class is the equivalent of java.nio.channels.FileLock. It represents a single lock on a particular region of a particular file.
- RemoteLockException.java. This class is used for exceptions pertaining to the remote locking protocol.
- RemoteLockConstants.java. This class contains some constants used in the communications protocol between the client and server.
As I mentioned earlier, you acquire a regular lock via the FileChannel object associated with a file:
RandomAccessFile raf =
new RandomAccessFile( "foo.txt", "rw" );
FileChannel fc = raf.getChannel();
FileLock lock = fc.lock( 0, 10, false );
In contrast, you get RemoteLocks from a RemoteLockClient object. When you create the RemoteLockClient object, you need to specify the hostname and port number:
RemoteLockClient client = new RemoteLockClient( hostname, port );
RemoteLock rl = client.lock( new File( filename ), position, size, false );
Note also that you must specify the file (via a File object) when calling lock(). This is because you are getting your lock from a RemoteLockClient, which is used for all locks you will acquire, regardless of the file on which you acquire them.
Releasing a RemoteLock is just like releasing a regular lock: