java.nio.channels.FileChannel中lock()与tryLock()方法的区别(Android Studio代码环境)

FileChannel中的lock()与tryLock()方法都是尝试去获取在某一文件上的独有锁(以下简称独有锁),可以实现进程间操作的互斥。区别在于lock()会阻塞(blocking)方法的执行,tryLock()则不会。

如果进程在执行lock()或tryLock()后获取到独有锁(return a FileLock object),那么进程会一直持有该锁到被释放(文件流被关闭 调用release() )。


如果进程P(A)持有独有锁:

1、进程P(B)执行lock()获取独有锁,则lock()所在方法会一直阻塞,直到独有锁被进程P(A)释放。

2、进程P(B)执行tryLock()获取独有锁,则tryLock()会抛出异常java.io.IOException: fcntl failed: EAGAIN (Try again)异常


测试代码:

private void processLockTest() {
    try {
        File file = new File(getFilesDir().getAbsolutePath() + File.separator + "lock.lock");
        FileOutputStream fos = new FileOutputStream(file);
        FileLock fl = null;
        boolean loop = true;
        int time = 0;
        LogUtil.log(android.os.Process.myPid() + "   " + "while start" + "  " + file.getAbsolutePath());
        while (loop) {
            time++;
            LogUtil.log(android.os.Process.myPid() + "   " + "loop 次数:" + time);
            if (fl == null) {
                LogUtil.log(android.os.Process.myPid() + "   " + "tryLock before" + " " + file.getAbsolutePath());
                try {
                    fl = fos.getChannel().tryLock();
                } catch (Exception e) {
                    e.printStackTrace();
                    LogUtil.log(android.os.Process.myPid() + "   " + "tryLock IOException" + " " + e.toString());
                }
                LogUtil.log(android.os.Process.myPid() + "   " + "tryLock after" + " " + file.getAbsolutePath());
            }
            if (fl != null) {
                while (loop) {
                    Thread.sleep(2000);
                    time++;
                    if (time == 5) {
                        fl.release();
                    }
                    if (time == 10) {
                        loop = false;
                    }
                    if (fl != null) {
                        LogUtil.log(System.currentTimeMillis() + "  " + android.os.Process.myPid() + "  " + "got");
                    } else {
                        LogUtil.log(System.currentTimeMillis() + "  " + android.os.Process.myPid() + "  " + "fl is null");
                    }
                }
            } else {
                LogUtil.log(System.currentTimeMillis() + "  " + android.os.Process.myPid() + "  " + "ungot");
            }
            Thread.sleep(2000);
        }
        LogUtil.log(android.os.Process.myPid() + "   " + "while over");
    } catch (Throwable t) {

    }
}


 
在两个进程中同时执行代码: 

new Thread(new Runnable() {
            @Override
            public void run() {
                LogUtil.log(android.os.Process.myPid() + "   " + "processLockTest start");
                processLockTest();
                LogUtil.log(android.os.Process.myPid() + "   " + "processLockTest over");
            }
        }).start();

打印结果:

06-29 16:51:15.199 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 25998   processLockTest start
06-29 16:51:15.199 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 25998   while start  /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:15.200 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 25998   loop 次数:1
06-29 16:51:15.200 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 25998   tryLock before /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:15.200 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 25998   tryLock after /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:15.211 25971-25971/com.ak.testerdemo:myservice E/liangyanmiao: MyService onCreate
06-29 16:51:15.211 25971-25971/com.ak.testerdemo:myservice E/liangyanmiao: MyService onStartCommand
06-29 16:51:15.211 25971-25971/com.ak.testerdemo:myservice E/liangyanmiao: MyService onStartCommand
06-29 16:51:15.212 25971-25971/com.ak.testerdemo:myservice E/liangyanmiao: MyService onStartCommand
06-29 16:51:15.216 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   processLockTest start
06-29 16:51:15.216 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   while start  /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:15.216 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   loop 次数:1
06-29 16:51:15.216 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock before /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:15.218 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock IOException java.io.IOException: fcntl failed: EAGAIN (Try again)
06-29 16:51:15.219 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock after /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:15.221 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 1498726275219  25971  ungot
06-29 16:51:17.201 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 1498726277201  25998  got
06-29 16:51:17.222 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   loop 次数:2
06-29 16:51:17.223 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock before /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:17.224 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock IOException java.io.IOException: fcntl failed: EAGAIN (Try again)
06-29 16:51:17.224 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock after /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:17.224 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 1498726277224  25971  ungot
06-29 16:51:19.201 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 1498726279201  25998  got
06-29 16:51:19.224 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   loop 次数:3
06-29 16:51:19.225 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock before /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:19.226 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock IOException java.io.IOException: fcntl failed: EAGAIN (Try again)
06-29 16:51:19.226 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock after /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:19.226 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 1498726279226  25971  ungot
06-29 16:51:21.203 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 1498726281202  25998  got
06-29 16:51:21.226 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   loop 次数:4
06-29 16:51:21.227 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock before /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:21.231 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock IOException java.io.IOException: fcntl failed: EAGAIN (Try again)
06-29 16:51:21.231 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock after /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:21.232 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 1498726281232  25971  ungot
06-29 16:51:23.203 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 1498726283203  25998  got
06-29 16:51:23.232 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   loop 次数:5
06-29 16:51:23.233 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock before /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:23.234 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   tryLock after /data/data/com.ak.testerdemo/files/lock.lock
06-29 16:51:25.204 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 1498726285204  25998  got
06-29 16:51:25.235 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 1498726285234  25971  got
06-29 16:51:27.205 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 1498726287205  25998  got
06-29 16:51:27.235 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 1498726287235  25971  got
06-29 16:51:29.207 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 1498726289207  25998  got
06-29 16:51:29.237 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 1498726289237  25971  got
06-29 16:51:31.221 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 1498726291221  25998  got
06-29 16:51:31.238 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 1498726291237  25971  got
06-29 16:51:33.223 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 1498726293223  25998  got
06-29 16:51:33.239 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 1498726293238  25971  got
06-29 16:51:35.224 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 25998   while over
06-29 16:51:35.225 25998-26150/com.ak.testerdemo:myservice2 E/liangyanmiao: 25998   processLockTest over
06-29 16:51:35.240 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   while over
06-29 16:51:35.240 25971-26152/com.ak.testerdemo:myservice E/liangyanmiao: 25971   processLockTest over

可以修改测试代码验证上述结论。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值