本文主要给多线程和数据流相关内容做笔记,对应原书的第15章和17章。
之前的内容请参考~~~
【七日阅书】1 计算思维和Java特性《Java程序设计与计算思维》
【七日阅书】2 Java的数据类型和流程控制《Java程序设计与计算思维》
【七日阅书】3 字符串、数组、集合、泛型《Java程序设计与计算思维》
【七日阅书】4 理解面向对象《Java程序设计与计算思维》
[【七日阅书】5 抽象和接口、异常处理](【七日阅书】5 抽象和接口、异常处理《Java程序设计与计算思维》_Code Metaverse-CSDN博客)
首先,我们要对程序执行有基本的概念。
一般的程序执行是顺序执行,就是这个时间内,只能运行一段代码片段,实现一部分功能。
多线程对应的多任务处理,则是一次程序运行对应多段代码,实现多种功能,就像下图游戏程序的例子。
我们可以通过继承Thread类,实现对线程的控制。
package com.example.demo.tool;
import lombok.SneakyThrows;
public class Task extends Thread {
int count = 0;
@SneakyThrows
@Override
public void run() {
while (true){
if(count > 5){
break;
}
System.out.print(this.getName() + ":" + String.valueOf(count) + "\r\n");
count ++;
Thread.sleep(500);
}
super.run();
}
}
在控制器,我们实例化三个Task并运行。
Task thread1 = new Task();
Task thread2 = new Task();
Task thread3 = new Task();
thread1.setName("task1");
thread2.setName("task2");
thread3.setName("task3");
thread1.start();
thread2.start();
thread3.start();
从运行结果可以看出,三个任务并不是按顺序执行的,并且也毫无关联。
Thread类本身就是Runnable接口的实现,我们在Runnable去控制线程,能做得更多。
package com.example.demo.tool;
import lombok.SneakyThrows;
/**
* 实现了Runnable接口
*/
public class TaskRunnable implements Runnable {
int count = 0;
@SneakyThrows
@Override
public synchronized void run() {
while (true){
if(count > 5){
break;
}
System.out.print(String.valueOf(count) + "\r\n");
count ++;
wait(500);
}
}
}
在控制器的调用阶段,我们让三个线程调用一个TaskRunnable,因为加入了关键字synchronized
,所以三个线程共享内存。
TaskRunnable taskRunnable = new TaskRunnable();
Thread thread1 = new Thread(taskRunnable,"task1");
Thread thread2 = new Thread(taskRunnable,"task2");
Thread thread3 = new Thread(taskRunnable,"task3");
thread1.start();
thread2.start();
thread3.start();
这里指的是从创建到结束的过程。
Java的输入输出都必须依靠内建的数据流对象处理。
System.out
是标准输出流,我们调试的时候常用的System.out.print
就是这里的。
字符数据流的作用是处理字符相关的输入输出。
下面是一些字符数据的处理代码示例,文章最后给出的地址有项目源码。
//CharArrayWriter用来接收数据
CharArrayWriter charArrayWriter = new CharArrayWriter();
charArrayWriter.write("cat1"); //可以是字符串或者下面的字节数组
char[] char01 = {
'c','a','t','2'};
charArrayWriter.write(char01);
char[] char02 = charArrayWriter.toCharArray(); //转字符数组
System.out.print(char02);
System.out.print("\r\n");
CharArrayReader charArrayReader = new CharArrayReader(char02);
CharArrayReader reader = new CharArrayReader(char02);
while (charArrayReader.read() != -1){
//读数据
System.out.print((char) reader.read());
}
System.out.print("\r\n");
//推荐使用
BufferedReader bufferedReader = new BufferedReader(new CharArrayReader(char02));
System.out.print(bufferedReader.readLine());
字节数据流主要用来存取8比特的字节数据,一般处理文本以及文件的上传下载。
其中输入数据流类的继承关系如下
输出流的继承关系如下
/**
* 字节数据流&文件流
*/
@PostMapping("/byte")
public void byteDemo(@RequestPart @RequestParam("file") MultipartFile file) throws IOException {
String filename = file.getOriginalFilename(); //获取文件名
byte[] fileContent = file.getBytes();
FileOutputStream fileOutputStream = new FileOutputStream("test.txt");
fileOutputStream.write(fileContent); //写入
fileOutputStream.close(); //关闭
File file2 = new File("test2.txt");
File file2rename = new File("test2rename.txt");
file2.renameTo(file2rename);
if(file2.createNewFile() == false){
System.out.print("文件新建失败");
}
file2.delete(); //删除
}
多线程对于Java程序效率的提升是明显的,synchronized
可以解决线程同步问题,但是要关注锁。
数据流在实际项目中,用的多的还是在文件读取和写入上,注意多用缓冲区,可以降低IO。
[小雨青年 / Java Demo · CODE CHINA (gitcode.net)](