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
可以修改测试代码验证上述结论。