锁——FileLock 文件锁

文件锁(FileLock),使用文件锁锁住文件后,其他进程不能操作读或写文件,除非当前进程release或unlock文件锁。

前两天看码云上的oim项目源码,该项目即使用了文件锁来防止同一账户重复登录(当然,该方法是不太合理的,因为用户换一台电脑或修改锁文件路径即可同一账户重复登录,但也是一个文件锁使用的不错的例子)

文件锁分为共享锁、独占锁,加锁方式有阻塞(lock())和非阻塞(tryLock())。

tryLock或lock时使用参数如fileChannel.tryLock(0L, Long.MAX_VALUE, true),即可使用共享锁

以下实例代码为独占锁实例,先运行FileLockTest 再运行BlockLock

FileLockTest .java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package file.lock;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

/**
 *
 * @author Administrator
 */
public class FileLockTest {


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws FileNotFoundException,IOException{
        File file;
        FileChannel fileChannel;
        RandomAccessFile randomAccessFile;
        

         String path = "C:\\Users\\Administrator\\Desktop\\lock\\my.lock";
         file = new File(path);
         if(!file.exists()){
            file.createNewFile();
        }
        randomAccessFile = new RandomAccessFile(file, "rw");
        //通过RandomAccessFile获取FileChannel
        fileChannel = randomAccessFile.getChannel();
     
        /*****
         * tryLock非阻塞,抢不到锁立即返回null
         * lock阻塞锁,抢不到锁一直等待
         */
        //通过FileChannel进行tryLock()
        final FileLock fileLock = fileChannel.tryLock();
       
        if(null == fileLock){
            System.out.println("老大,属下无能,文件已经被其他进程锁住!");
        }else{
            if(fileLock.isValid()){
                System.out.println("老大,本进程已经先行一步锁住了文件了!");
                 new Thread(
                    new Runnable() {
                        @Override
                        public void run() {
                            try {
                                //当前文件应该处于被锁住状态,20后解锁,阻塞锁lock会立即获取锁
                                Thread.sleep(20 * 1000);
                                randomAccessFile.read();
                                System.out.println("我读完了,我要释放锁!");
                                fileLock.release();
                            } catch (Exception ex) {
                                ex.printStackTrace();
                            }
                        }
                    }
                ).start();
            }

        }
         
       
        exit();
      
    }
    
    
    
    private static void exit(){
        while (true) {            
            try {
                Thread.sleep(10 * 10000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
      
    
    
    }
}

 

BlockLock.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package file.lock;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

/**
 *
 * @author Administrator
 */
public class BlockLock {
    
    
    public static void main(String[] args) throws FileNotFoundException, IOException {
        File file;
        FileChannel fileChannel;
        RandomAccessFile randomAccessFile;
         String path = "C:\\Users\\Administrator\\Desktop\\lock\\my.lock";
         file = new File(path);
         if(!file.exists()){
            file.createNewFile();
        }
        randomAccessFile = new RandomAccessFile(file, "rw");
        //通过RandomAccessFile获取FileChannel
        fileChannel = randomAccessFile.getChannel();
        
        
         FileLock tempLock = fileChannel.tryLock();
        if(null == tempLock){
                System.out.println("我拿不到文件锁,交给阻塞锁lock()拿吧!");
                System.out.println("开始测试阻塞锁...");
                FileLock fileLock2 = fileChannel.lock();
                if(null == fileLock2){

                }else{
                    if(fileLock2.isValid()){
                            System.out.println("老大,那小子一释放锁,就被我抢到了!厉害不!");
                    }
                }
        }else{
                 System.out.println("使用非阻塞锁拿到了文件锁...");

        
        }
        
    }
}

 

运行结果如下:

FileLockTest:

老大,本进程已经先行一步锁住了文件了!
我读完了,我要释放锁!

BlockLock:

我拿不到文件锁,交给阻塞锁lock()拿吧!
开始测试阻塞锁...
老大,那小子一释放锁,就被我抢到了!厉害不!

 

 

如有错误,欢迎指正

end

 

 

你可能感兴趣的:(Java)