7天掌握NIO和SOCKET,第四天,通道锁的读写

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: 另一个程序已锁定文件的一部分,进程无法访问。
        * */
    }
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值