import java.io.*; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; public class test_03 { public static void main(String[] args) throws Exception { //锁操作:FileLock lock(long position,long size,boolean shared) //只锁定position到size部分,若是通道扩大,不锁定扩大部分,要是想锁定扩大部分,size传入大于或等于预计文件最大值 //零参数,是锁定Long.MAX_VALUE的部分 //锁定是同步的 //method_01();
private static void method_01() throws Exception{
RandomAccessFile randomAccessFileA = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
RandomAccessFile randomAccessFileB = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel1 = randomAccessFileA.getChannel();
FileChannel fileChannel2 =randomAccessFileB.getChannel();
Thread thread1 = new Thread(){
@Override
public void run() {
try {
System.out.println("A begin");
fileChannel1.lock(1,2,false);
System.out.println("A end");
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread thread2 = new Thread(){
@Override
public void run() {
try {
System.out.println("B begin");
fileChannel1.lock(1,2,false);
System.out.println("B end");
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(5_00);
thread2.start();
//输出:证明为同步的,阻塞等待
/*
A begin
A end
B begin
Exception in thread "Thread-1" java.nio.channels.OverlappingFileLockException
at sun.nio.ch.SharedFileLockTable.checkList(FileLockTable.java:255)
at sun.nio.ch.SharedFileLockTable.add(FileLockTable.java:152)
at sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:1062)
at wxf.cn.chapter_1.day_04.test_03$2.run(test_03.java:41)
* */
}
//验证异常:另一个线程关闭了此通道,发生该异常,此方法具有随机性,所以循环一万次,总会有结果 //for (int i = 0 ; i < 10000 ; i++) //method_02();
private static void method_02() throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
Thread thread1 = new Thread(){
@Override
public void run() {
try {
fileChannel.lock(1,2,false);
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread thread2 = new Thread(){
@Override
public void run() {
try {
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(1);
thread2.start();
/*输出:
java.nio.channels.ClosedChannelException
at sun.nio.ch.FileChannelImpl.ensureOpen(FileChannelImpl.java:110)
at sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:1055)
at wxf.cn.chapter_1.day_04.test_03$3.run(test_03.java:77)
* */
}
//异常验证2:ClosedChannelException //method_03();
private static void method_03() throws Exception{
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\10167\\Desktop\\test.txt");
FileChannel fileChannel = fileOutputStream.getChannel();
Thread thread1 = new Thread(){
@Override
public void run() {
try {
for (int i = 0; i < 1000000; i++) {
System.out.println(i);
}
fileChannel.lock(1,2,false);
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(500);
thread1.interrupt();
fileChannel.close();
fileOutputStream.close();
/*输出:正在等待获取锁定,此时却中断了线程,报错:ClosedChannelException
999998
999999
java.nio.channels.ClosedChannelException
at sun.nio.ch.FileChannelImpl.ensureOpen(FileChannelImpl.java:110)
at sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:1055)
at wxf.cn.chapter_1.day_04.test_03$5.run(test_03.java:119)
* */
}
//共享锁:自己和别人都不能写,自己和别人都能度 //1:共享锁:自己不能写: //method_04();
private static void method_04() throws Exception{
RandomAccessFile fileOutputStream = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel = fileOutputStream.getChannel();
fileChannel.lock(1,2,true);
fileChannel.write(ByteBuffer.wrap("年后中国".getBytes()));
/*输出:Exception in thread "main" java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。
* 证明共享锁自己不能写,中文是操作系统为中文,是操作系统层面的处理
* */
}
//2:共享锁,别人不能写 //method_05();
private static void method_05() throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
Thread thread1 = new Thread(){
@Override
public void run() {
try {
fileChannel.lock(1,2,true);
try {
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(1_000);
Thread thread2 = new Thread(){
@Override
public void run() {
try {
fileChannel.write(ByteBuffer.wrap("你好".getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread2.start();
/*输出:java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。
证明别人也不能读,是操作系统层面的,返回的中文错误信息,就是操作系统返回的
* */
}
//3:共享锁,自己能读 //method_06();
private static void method_06() throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
Thread thread1 = new Thread(){
@Override
public void run() {
try {
fileChannel.read(byteBuffer);
byteBuffer.rewind();
for (int i = 0; i < fileChannel.size(); i++) {
System.out.print((char) byteBuffer.get());
}
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(500);
System.out.println(byteBuffer.position());
}
//4:共享锁,别人能读 //method_07();
private static void method_07() throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
Thread thread1 = new Thread(){
@Override
public void run() {
try {
fileChannel.lock(0,6,true);
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(500);
Thread thread2 = new Thread(){
@Override
public void run() {
ByteBuffer byteBuffer = ByteBuffer.allocate(6);
try {
fileChannel.read(byteBuffer);
byteBuffer.rewind();
for (int i = 0; i < byteBuffer.limit(); i++) {
System.out.print((char) byteBuffer.get());
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread2.start();
}
//独占锁:自己能写能读,别人不能写不能读 //1:独占锁:自己能写: //method_08();
private static void method_08() throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
fileChannel.lock(0,6,false);
fileChannel.write(ByteBuffer.wrap("你好".getBytes()));
}
//2:独占锁,别人不能写 //method_09();
private static void method_09() throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
Thread thread1 = new Thread(){
@Override
public void run() {
try {
fileChannel.lock(0,6,false);
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread thread2 = new Thread(){
@Override
public void run() {
try {
RandomAccessFile randomAccessFile1 = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel1 = randomAccessFile1.getChannel();
fileChannel1.write(ByteBuffer.wrap("好饿".getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(500);
thread2.start();
/*报错:java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。
* */
}
//3:独占锁,自己能读 //method_10();
private static void method_10() throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
fileChannel.read(byteBuffer);
byteBuffer.rewind();
CharBuffer charBuffer = Charset.forName("utf-8").decode(byteBuffer);
for (int i = 0; i < charBuffer.limit(); i++) {
System.out.print(charBuffer.get());
}
}
//4:独占锁,别人不能读 method_11();
private static void method_11() throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
fileChannel.lock(1,6,false);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(){
@Override
public void run() {
try {
RandomAccessFile randomAccessFile1 = new RandomAccessFile("C:\\Users\\10167\\Desktop\\test.txt","rw");
FileChannel fileChannel1 = randomAccessFile1.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
fileChannel1.read(byteBuffer);
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(500);
thread2.start();
/*报错:java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。
* */
}
}
}