7天掌握NIO和SOCKET,第四天,lock的无参方法和tryLock方法,强制写入内存的force方法和将通道文件区域自己解映射到内存的MappedByteBuffer

import java.io.File;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public class test_05 {
    public static void main(String[] args) throws Exception {
        //FileLoc lock()的无参数方法为:
        /*源码:
        public final FileLock lock() throws IOException {
            return lock(0L, Long.MAX_VALUE, false);
        }
        *该方法与FileLock lock(position, MAX_VALUE, false)的特性完全一样
        */

        //tryLock(),此方法不会阻塞,如果另一个程序保持着一个重叠锁而无法获得锁定时,此方法返回null,如果由于其他原因,则抛出相应的异常
        //test_05_01和test_05_02

        //tryLock()的无参数和tryLock(0,Long.MAX_VALUE,false);特性一样

        //isValid:测试锁的有效性,isShared:独占还是共享
        //method_01();

    private static void method_01() throws Exception{
        File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        System.out.println("filechannel.hashcode() = "+fileChannel.hashCode());
        FileLock lock = fileChannel.lock(1, 10, true);
        System.out.println("A position = "+lock.position()+" A size = "+lock.size() +"A.isValid = "+lock.isValid()+ " A isShared = "+lock.isShared()
                +" A channel().hashcode() = "+lock.channel().hashCode()+" acquiredBy().hashcode() = "+lock.acquiredBy().hashCode());
        lock.release();
        lock = fileChannel.lock(1,10,false);
        System.out.println("A position = "+lock.position()+" A size = "+lock.size() +"A.isValid = "+lock.isValid()+ " A isShared = "+lock.isShared()
                +" A channel().hashcode() = "+lock.channel().hashCode()+" acquiredBy().hashcode() = "+lock.acquiredBy().hashCode());
        lock.close();
        fileChannel.close();
        System.out.println("A position = "+lock.position()+" A size = "+lock.size() +"A.isValid = "+lock.isValid()+ " A isShared = "+lock.isShared()
                +" A channel().hashcode() = "+lock.channel().hashCode()+" acquiredBy().hashcode() = "+lock.acquiredBy().hashCode());
        /*输出
        filechannel.hashcode() = 460141958
        A position = 1 A size = 10A.isValid = true A isShared = true A channel().hashcode() = 460141958 acquiredBy().hashcode() = 460141958
        A position = 1 A size = 10A.isValid = true A isShared = false A channel().hashcode() = 460141958 acquiredBy().hashcode() = 460141958
        A position = 1 A size = 10A.isValid = false A isShared = false A channel().hashcode() = 460141958 acquiredBy().hashcode() = 460141958
        * */
    }
        //overlaps(long position,long size):判断此锁是否与给定的锁定区域重叠,当且仅当至少重叠一个字节时,返回true
        //method_02();

    private static void method_02() throws Exception{
        File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        FileLock lock = fileChannel.lock(1, 4, false);
        System.out.println(lock.overlaps(3,6));
        System.out.println(lock.overlaps(5,6));
        /*输出
        true
        false
        * */
    }
        //force(boolean metaData):强制将所有对通道的更新写入包含的文件设备,尽量减少数据丢失,耗费资源多,事件至少也要200倍以上
        //metaData为false只是写入存储设备,为true则必须写入对文件内容和元素据的更新
        //此参数是否有效,取决于底层操作系统
        //method_03();

    private static void method_03() throws Exception{
        Thread thread1 = new Thread(){
            @Override
            public void run() {
                try {
                    File file = new File("C:\\Users\\10167\\Desktop\\test3.txt");
                    if(!file.exists()){
                        file.createNewFile();
                    }
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    FileChannel fileChannel = fileOutputStream.getChannel();
                    Long startTime = System.currentTimeMillis();
                    for (int i = 0; i < 5000; i++) {
                        fileChannel.write(ByteBuffer.wrap("abcdef".getBytes()));
                    }
                    Long endTime = System.currentTimeMillis();
                    System.out.println(endTime - startTime);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        };
        Thread thread2 = new Thread(){
            @Override
            public void run() {
                try {
                    File file = new File("C:\\Users\\10167\\Desktop\\test4.txt");
                    if(!file.exists()){
                        file.createNewFile();
                    }
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    FileChannel fileChannel = fileOutputStream.getChannel();
                    Long startTime = System.currentTimeMillis();
                    for (int i = 0; i < 5000; i++) {
                        fileChannel.write(ByteBuffer.wrap("abcdef".getBytes()));
                        fileChannel.force(false);
                    }
                    Long endTime = System.currentTimeMillis();
                    System.out.println(endTime - startTime);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        };

        thread1.start();
        thread2.start();
        /*输出
        23
        5459
        * */
    }
        //将通道文件区域直接映射到内存
        //MappedByteBuffer map(FileChannel.MapMode mode , long position , long size )
        //三种模式:只读,读写,专用
        //测试该方法
        //method_04();

    private static void method_04() throws Exception{
        File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY,0,5);
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY,2,2);

        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        Thread.sleep(500);
        //此句超出映射范围
        System.out.println((char)buffer.get()+" position="+buffer.position());
        /*输出
        a position=1
        b position=2
        c position=3
        d position=4
        e position=5
        c position=1
        d position=2
        Exception in thread "main" java.nio.BufferUnderflowException
        * */
    }
        //只读:试图修改缓冲区抛出异常
        //method_05();

    private static void method_05() throws Exception{
        File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY,0,5);
        buffer.putChar('1');
        //抛出异常:Exception in thread "main" java.nio.ReadOnlyBufferException
    }
        //读写:对得到的缓冲区的更改最终将传播到文件,该更改对映射到同一文件的其他程序不一定是可见的
        //method_06();

    private static void method_06() throws Exception{
        File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,5);
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        buffer.position(0);
        buffer.put((byte)'a');
        buffer.put((byte)'b');
        buffer.put((byte)'c');
        buffer.put((byte)'d');
        buffer.put((byte)'e');
        fileChannel.close();
        randomAccessFile.close();
        /*输出
        a position=1
        b position=2
        c position=3
        d position=4
        e position=5
        执行完后:文件内为:abcde,对缓冲区的更改最终传播到文件
        * */
    }
        //专用:对得到的缓冲区的更改最终不会传播到文件,该更改对映射到同一文件的其他程序不可见
        //method_07();

    private static void method_07() throws Exception{
        File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.PRIVATE,0,5);
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        System.out.println((char)buffer.get()+" position="+buffer.position());
        buffer.position(0);
        buffer.put((byte)'1');
        buffer.put((byte)'2');
        buffer.put((byte)'3');
        buffer.put((byte)'4');
        buffer.put((byte)'5');
        fileChannel.close();
        randomAccessFile.close();
        /*输出
        a position=1
        b position=2
        c position=3
        d position=4
        e position=5
        文件内容:abcde,最终缓冲区的更改没有传播到文件
        * */
    }
        //MappedByteBuffer load和MappedByteBuffer isLoaded()
        //将缓冲区内容加载到物理内存中,最大限度地保证返回时此缓冲区地内容位于物理内存中,可能会导致一些页面错误,并导致I/O操作
        //isLoaded返回false也不是缓冲区内容不位于物理内存中,只是一个提示,而不是保证
        method_08();

    private static void method_08() throws Exception{
        File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,10);
        //System.out.println(buffer+" "+buffer.isLoaded());
        buffer.load();
         System.out.println(buffer+" "+buffer.isLoaded());
    }
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值