今天是来到天亮的第23天,今天主要学习了IO流,多线程。
IO流主要讲了昨日练习题
1.用IO流复制文件:
public class DaiMa2 {
public static void main(String[] args) {
try (
FileInputStream fis=new FileInputStream("C:\\a.zip");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("d://a.zip");
BufferedOutputStream bos = new BufferedOutputStream(fos);
){
// 创建byte数组,增加效率
byte[] bytes=new byte[10240];
int temp=0;
while((temp=bis.read(bytes))!=-1){
bos.write(bytes,0,temp);
}
// 清空缓冲区
bos.flush();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
2.文件input.txt中存放着10行数字,为0至6区间的整数,求10行数字去重后还有多少行?分别是哪些数字?排序序出。
public class DaiMa3 {
public static void main(String[] args) throws IOException {
try (Reader fis =new FileReader("C://_java//input.txt");
BufferedReader bReader =new BufferedReader(fis);){
Set set=new TreeSet();
String string=null;
while((string=bReader.readLine())!=null){
Integer integer=Integer.parseInt(string);
set.add(integer);
}
System.out.println("还有"+set.size()+"行");
System.out.println(set);
} catch (Exception e) {
// TODO: handle exception
}
}
}
3 多文件内容合并读问题: 任意给定多个文本文件路径合并为一个大的文本文件,并保存名为merge.txt。
1)、如给定"one.txt”,“two.txt”,“three.txt"三个文本文件路径
2)、内部分别存储内容"内容One"、“内容Two”、“内容Three"
3)、合并完成后merge.txt的结果为三行文字,分别为“内容One"、"内容Two"、"内容Three"
public class DaiMa4 {
public static void main(String[] args) {
try (
FileReader fiStream1=new FileReader("C://_java//one.txt");
FileReader fiStream2=new FileReader("C://_java//two.txt");
FileReader fiStream3=new FileReader("C://_java//three.txt");
FileWriter fileOutputStream=new FileWriter("D://_java//merge.txt");
BufferedReader bReader1=new BufferedReader(fiStream1);
BufferedReader bReader2=new BufferedReader(fiStream2);
BufferedReader bReader3=new BufferedReader(fiStream3);
BufferedWriter bufferedWriter=new BufferedWriter(fileOutputStream)
){
String string=null;
while ((string = bReader1.readLine()) != null) {
bufferedWriter.write(string);
bufferedWriter.newLine();
}
string = null;
while ((string = bReader2.readLine()) != null) {
bufferedWriter.write(string);
bufferedWriter.newLine();
}
string = null;
while ((string = bReader3.readLine()) != null) {
bufferedWriter.write(string);
bufferedWriter.newLine();
}
bufferedWriter.flush();
} catch (Exception e) {
// TODO: handle exception
}
}
}
4 使用递归,完成目录复制(新增规则,只复制java文件)
public class DaiMa5 {
public static void main(String[] args) {
// new file类对象f地址为要复制的
File f = new File("C:\\_java\\workspace\\_day02");
checkMunu(f);
System.out.println("复制完成");
}
public static void checkMunu(File f) {
if (f.isFile()) {
// 复制操作
// 原文件路径
String filePath = f.getAbsolutePath();
// 判断每个文件是否以.java结尾
if(filePath.endsWith(".java")){
String newFilePath = "D"+filePath.substring(1);
File file = new File(newFilePath).getParentFile();
// 判断目标路径中,是否有对应的文件夹
if (!file.exists()) {
// 不存在就创建注意mkdirs和mkdir区别
file.mkdirs();
}
// 复制
// 输入流
try (FileInputStream fis = new FileInputStream(filePath);
// 缓冲
BufferedInputStream bis = new BufferedInputStream(fis);
// 输出
FileOutputStream fos = new FileOutputStream(newFilePath,true);
BufferedOutputStream bos = new BufferedOutputStream(fos);
) {
// 缓冲数组
byte[] bytes = new byte[999999];
int temp = -1;
// read相当一个指针把
while( (temp = bis.read(bytes)) != -1 ){
// 将每个文件复制到对应文件
bos.write(bytes, 0, temp);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
}
return;
}}
File[] fs = f.listFiles();
// 能到这里 说明是 目录
// 获取所有子文件
// String filePath = f.getAbsolutePath();
if (fs == null || fs.length == 0) {
// 如果文件夹是空的,就拼接目标目录,然后创建目录
File newFile = new File("D" +f.getAbsolutePath().substring(1));
newFile.mkdirs();
return;
}
// 遍历当前目录所有子文件.
for (File file : fs) {
checkMunu(file);
}
}
}
多线程:
程序、进程、线程:
程序:程序是指令的集合。是静态的。
进程:是程序的一次执行过程,或是正在运行的一个程序。是一个动态的过程:有它自身的产生、存在和消亡的过程。——生命周期
线程:线程(thread),进程可进一步细化为线程,是一个程序内部的一条执行路径。若一个进程同一时间并行执行多个线程,就是支持多线程的。
单核CPU和多核CPU:
-
- 单核CPU,其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程 的任务。例如:虽然有多车道,但是收费站只有一个工作人员在收费,只有收了费 才能通过,那么CPU就好比收费人员。如果有某个人不想交钱,那么收费人员可以 把他“挂起”(晾着他,等他想通了,准备好了钱,再去收费)。但是因为CPU时 间单元特别短,因此感觉不出来。
- 如果是多核的话,才能更好的发挥多线程的效率。(现在的服务器都是多核的)
- 一个Java应用程序java.exe,其实至少有三个线程:main()主线程,gc() 垃圾回收线程,异常处理线程。当然如果发生异常,会影响主线程。
并行与并发:
并行:多个CPU同时执行多个任务。比如:多个人同时做不同的事。
并发:一个CPU(采用时间片)同时执行多个任务。比如:秒杀活动、多个人做同一件事。
多线程优点:
- 提高应用程序的响应。对图形化界面更有意义,可增强用户体验。
- 提高计算机系统CPU的利用率
- 改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改
何时需要多线程:
- 程序需要同时执行两个或多个任务。
- 程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
- 需要一些后台运行的程序时。
- 线程的创建和使用:
方式一:Tread类
-
- Thread():创建新的Thread对象
- Thread(String threadname):创建线程并指定线程实例名
- Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接口中的run方法
-
- Thread(Runnable target, String name):创建新的Thread对象创建过程
过程:
- 继承Thread类
- 定义子类继承Thread类。
- 子类中重写Thread类中的run方法。
- 创建Thread子类对象,即创建了线程对象。
- 调用线程对象start方法:启动线程,调用run方法。
定义和使用代码:
Thread thread =new processor();
thread.start();
class processor extends Thread{
public void m1(){
}
public void run(){
for (int i = 0; i < 10; i++) {
System.out.println("test1();"+i);
}
}
}
方式二:
实现Runnable接口
过程:
- 定义子类,实现Runnable接口。
- 子类中重写Runnable接口中的run方法。
- 通过Thread类含参构造器创建线程对象。
- 将Runnable接口的子类对象作为实际参数传递给Thread类的构造器中。
- 调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法。
定义和使用代码:
Thread thread=new Thread(new processor1());
thread.start();
class processor1 implements Runnable {
public void m1(){
}
public void run(){
for (int i = 0; i < 10; i++) {
System.out.println("test1();"+i);
}
}
}