1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
// FileLock.java
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
/**
* "locks" a resource by using the file system as storage
* file has 1 line
* <incarnation> <last ping time in millis>
*/
public class FileLock {
public FileLock( String logicalName )
throws IOException {
_file = new File( "/tmp/java-fileLock-" + logicalName );
_incarnation = "xxx" + Math.random() + "yyy";
if ( ! _file.exists() ) {
FileOutputStream fout = new FileOutputStream( _file );
fout.write( "\n".getBytes() );
fout.close();
}
}
/**
* takes lock
* if someone else has it, blocks until the other one finishes
*/
public void lock()
throws IOException {
if ( _lock != null )
throw new IllegalStateException( "can't lock when you're locked" );
try {
_semaphore.acquire();
}
catch ( InterruptedException ie ) {
throw new RuntimeException( "sad" , ie );
}
_raf = new RandomAccessFile( _file , "rw" );
_lock = _raf.getChannel().lock();
}
public void unlock()
throws IOException {
if ( _lock == null )
throw new IllegalStateException( "can't unlock when you're not locked" );
_lock.release();
_semaphore.release();
_locked = false;
}
final File _file;
final String _incarnation;
private RandomAccessFile _raf;
private java.nio.channels.FileLock _lock;
private boolean _locked;
private static Semaphore _semaphore = new Semaphore(1);
public static void main( final String[] args )
throws Exception {
List<Thread> threads = new ArrayList<Thread>();
for ( int i=0; i<3; i++ ) {
threads.add( new Thread() {
public void run() {
try {
FileLock lock = new FileLock( args[0] );
long start = System.currentTimeMillis();
lock.lock();
System.out.println( "time to lock:\t" + (System.currentTimeMillis()-start) );
Thread.sleep( Integer.parseInt( args[1] ) );
lock.unlock();
System.out.println( "total time:\t" + (System.currentTimeMillis()-start) );
}
catch ( Exception e ) {
e.printStackTrace();
}
}
} );
}
for ( Thread t : threads ) {
t.start();
}
for ( Thread t : threads ) {
t.join();
}
}
}
|