第九次总结 多线程

1.什么是线程,进程 ,程序?

2.如何实现多线程的程序?

3.线程的状态?

4.线程中的常用方法?

5.使用多线程复制一个文件?


1.什么是线程,进程 ,程序?

程序:程序是安装在硬盘中的一堆能完成一定任务的文件


进程:程序启动之后,就会至少有一个进程
每个进程是一个独立的运行单元
每个进程都独占一块内存

线程:线程是一个进程内部的多个并行的运行单元
每一个线程都有一块独立的内存空间
同一个进程的多个线程之间可以通过进程来共享内存


2.如何实现多线程的程序?

a.定义一个类,继承Thread类,重写Thread的run方法,将需要同时执行的代码放到run方法中
用法:创建线程对象
调用线程的start方法


b.定义一个类,实现Runnable接口,重写Runnable的run方法


c.定义一个类,继承TimerTask[定时任务],重写run方法


3.线程的状态?

  1. New Thread 新建状态 线程对象已创建,但还没有执行start
  2. Runnable 就绪状态[可运行状态] 已经调用了线程的start方法,但还没有还是执行run
  3. Running 运行中 线程正在执行run方法
  4. Nt Run 阻塞状态[挂起状态] 线程正在sleep或者wait
  5. Dead 死亡状态 线程的run方法执行完毕或者进程被终止

4.线程中的常用方法?

Thread.currentThread(); 获得当前线程对象


getName() 获得线程的名字


getId() 获得线程的标识
setName() 设置线程的名字

sleep(time) 线程睡觉 time毫秒
当过了time毫秒之后,线程自动恢复执行
在线程sleep的时候,如果访问了其它资源 ,将继续占据该资源

join() 执行完该线程,在执行后面的代码


yield() 让出自己的执行时间


interrupt() 中断Sleep


5.使用多线程复制一个文件?

FileCopy类

package xiancheng.copy;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.TreeSet;

/**
 * 用来复制文件的类
 */

public class FileCopy extends Thread{
    public static final TreeSet<String> paths=new TreeSet<>();

    private String path;
    private long start;
    private long length;

    public FileCopy(String path, long start, long length) {
        this.path = path;
        this.start = start;
        this.length = length;
    }

    public void run(){
        try {
            copy(path,start,length);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    /**
     * 复制文件数据的方法
     * @param path 要复制的文件路径
     * @param start 开始复制文件数据的起始字节
     * @param length 要复制的字节数
     */
    public void copy(String path,long start,long length)throws  Exception{
        //创建文件字节输入流
        FileInputStream fis = new FileInputStream(path);
        //将每一个线程复制的数据作为一个单独的文件
        String dest =path+this.getName()+".bak";
        //将临时文件名保存起来
        paths.add(dest);
        FileOutputStream fos =new FileOutputStream(dest);

        //将文件字符流包装成缓冲字符流
        BufferedInputStream bis =new BufferedInputStream(fis);
        BufferedOutputStream bos =new BufferedOutputStream(fos);

        //在进行读写数据之前,先要确定当前线程从哪个位置开始读数据
        //跳过不需要读取的字节
        bis.skip(start);

        //读取个数为length个,读取一个就写一个
        for (long i=0;i<length;i++){
            int t=bis.read();
            bos.write(t);
        }
        bos.flush();
    }
}

FileMerge类
package xiancheng.copy;

import java.io.*;

/**
 * 合并多个线程复制的文件
 */
public class FileMerge extends Thread{
    private String dest;

    public FileMerge(String dest) {
        this.dest = dest;
    }

    public void run(){
     try {
         merge(dest);
     }catch (Exception ex){
         ex.printStackTrace();
     }
    }
    //将多个线程复制完的临时文件合并成一个文件
    public void merge(String dest)throws Exception{
        //根据最终需要保存的文件路径创建一个文件输出流,使用追加模式
        FileOutputStream fos =new FileOutputStream(dest,true);
        BufferedOutputStream bos =new BufferedOutputStream(fos);

        //遍历存放文件名的Set
        for (String str :FileCopy.paths){
            //根据临时文件路径str创建输入流
            FileInputStream fis =new FileInputStream(str);
            BufferedInputStream bis =new BufferedInputStream(fis);
            int t=bis.read();
            while (t!=-1){
                bos.write(t);
                t=bis.read();
            }
            System.out.println(str);

            File file=new File(str);
            if(file.exists()){
                file.delete();
                System.out.println("文件已删除");
            }

            bos.flush();
            bis.close();

        }
        bos.flush();
        fos.close();
    }
    }
FileCopyTest测试类
package xiancheng.copy;

import java.io.File;


public class FileCopyTest {
    public static void main(String[] args) throws Exception {
        String path = "D:\\11\\a\\线程20200727.zip";
        String dest = "D:\\11\\a\\aa_fujian.zip";

        //确定总共5个线程,计算每个线程需要复制多少个字节
        File f = new File(path);
        long length = f.length();

        //每个线程需要复制的字节数
        long count = length / 5;
        //最后一个线程需要处理不能整除的部分字节
        long countLast = count + length % 5;

        FileCopy fc = null;
        //开启线程,准备复制
        for (int i = 0; i < 5; i++) {
            //要处理最后一个线程需要复制的字节数
            long size = count;
            if (i == 4) {
                size = countLast;
            }
            fc = new FileCopy(path, count * i, size);
            fc.setName("thread" + i);
            //启动线程
            fc.start();
        }
        fc.join();

        //创建一个用来合并数据的线程
        FileMerge fh = new FileMerge(dest);
        fh.start();
    }
}

猜你喜欢

转载自www.cnblogs.com/zxxb/p/13400724.html