线程的实际运用

问题:利用子线程完成一个较大文件的拷贝。

由于文件过大,如果只用主线程进行拷贝,会比较慢,所以我们可以利用多个子线程进行文件的拷贝,将文件划分成小块,减少一个线程的工作量,提高了CPU的利用率,从而提高了工作效率。

具体问题分析如下:

假设文件的大小为4G,我们需要4个线程并发进行对文件的拷贝,有以下的问题需要解决:
1、每个线程所拷贝的文件的大小(如何划分)
2、每个子线程的拷贝起始位置的定位
3、拷贝文件的方式(所选取的流)

设计方案

子线程:
选取RandomAccessFile流,因为它支持读取和写入随机访问文件,其中的seek()方法可以将指针移到固定位置,将读取的内容写入目的文件

class MyThread extends Thread{
    private String srcPath;
    private String dextPath;
    private long startIndex;
    private long endIndex;
   //构造函数子线程 4个参数:起始位置,终止位置,源地址,目的地址
    public MyThread(String srcPath,String dextPath,long startIndex,long endIndex){
        this.srcPath = srcPath;
        this.dextPath = dextPath;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
    }
    @Override
    public void run() {
        try {
            RandomAccessFile src = new RandomAccessFile(srcPath,"r");
            RandomAccessFile dest = new RandomAccessFile(dextPath, "rw");
            //使文件移动到指定文件
            src.seek(startIndex);
            dest.seek(startIndex);
            long index = startIndex;
            byte[]bytes = new byte[1024];
            int n;
            while ((n = src.read(bytes))!=-1){
                index += n;
                dest.write(bytes,0,n);
                if (index >= endIndex){
                    break;
                }
            }
            src.close();
            dest.close();
        }  catch (IOException e) {
            e.printStackTrace();
        }
    }
}

功能函数:
里面包括了主线程,它的主要作用就是划分子线程的读取范围(假设是4个子线程共同拷贝4G的文件)
*第一个线程读取0-1G: 0-length
*第二个线程读取1G-2G: length+1…2length
*第三个线程读取2G-3G: 2length…3length
*第四个线程读取3G-4G: 3length…file.length(处理直到文件结尾的内容)

public static void MutilThreadCopyFile(String srcPath, String destPath, Integer ThreadNum) throws FileNotFoundException {
        //参数校验,判断文件是否为空,线程数是否不合格
        if (srcPath == null || destPath == null || ThreadNum < 1) {
            System.out.println("输入有误,无法执行!");
        }
        //文件的划分
        File file = new File(srcPath);
        //文件的长度
        long fileLenght = file.length();
        long subTLength = fileLenght / ThreadNum;//每个线程需要处理的数据量
        //主线程处理,将文件分给子线程,让子线程进行处理
        for (int i = 0; i < ThreadNum - 1; i++) {
            MyXianCheng myXianCheng = new MyXianCheng(srcPath, destPath, i * subTLength, (i + 1) * subTLength);
            myXianCheng.start();
        }
          //将剩余部分全部交给最后一个线程处理
        MyXianCheng myXianCheng = new MyXianCheng(srcPath, destPath, ThreadNum * subTLength, 1 * fileLenght);
        myXianCheng.start();
    }

主函数:
* srcPath:源路径
* destPath:目标地址
* ThreadNum:线程数量

    public static void main(String[] args) throws FileNotFoundException {
        String srcPath = "D:\\1.txt";
        String dsetPath = "D:\\2.txt";
        System.out.println("请输入需要的子线程个数。");
        Scanner sc = new Scanner(System.in);
        Integer n = sc.nextInt();
        System.out.println("文件开始拷贝……");
        MutilThreadCopyFile(srcPath,dsetPath,n);
        new Thread().start();
        System.out.println("文件拷贝结束……");
    }

运行展示:
在这里插入图片描述
源文件:1.txt
在这里插入图片描述
目标文件:2.txt
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值