1.什么是线程,进程 ,程序?
2.如何实现多线程的程序?
3.线程的状态?
4.线程中的常用方法?
5.使用多线程复制一个文件?
1.什么是线程,进程 ,程序?
程序:程序是安装在硬盘中的一堆能完成一定任务的文件
进程:程序启动之后,就会至少有一个进程
每个进程是一个独立的运行单元
每个进程都独占一块内存
线程:线程是一个进程内部的多个并行的运行单元
每一个线程都有一块独立的内存空间
同一个进程的多个线程之间可以通过进程来共享内存
2.如何实现多线程的程序?
a.定义一个类,继承Thread类,重写Thread的run方法,将需要同时执行的代码放到run方法中
用法:创建线程对象
调用线程的start方法
b.定义一个类,实现Runnable接口,重写Runnable的run方法
c.定义一个类,继承TimerTask[定时任务],重写run方法
3.线程的状态?
- New Thread 新建状态 线程对象已创建,但还没有执行start
- Runnable 就绪状态[可运行状态] 已经调用了线程的start方法,但还没有还是执行run
- Running 运行中 线程正在执行run方法
- Nt Run 阻塞状态[挂起状态] 线程正在sleep或者wait
- 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(); } }