黑马程序员技术交流社区

标题: [石家庄校区]7-10笔记 [打印本页]

作者: 859182973    时间: 2018-11-26 15:30
标题: [石家庄校区]7-10笔记
本帖最后由 859182973 于 2018-11-26 15:38 编辑

线程间的通信
概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同

为什么要处理线程间通信:
多个线程并发执行时, 在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务,并且我们希望他们有规律的执行, 那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据。

如何保证线程间通信有效利用资源:
多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个变量的使用或操作。 就是多个线程在操作同一份数据时, 避免对同一共享变量的争夺。也就是我们需要通过一定的手段使各个线程能有效的利用资源。而这种手段即—— 等待唤醒机制。

线程之间需要合作



什么是等待唤醒机制
这是多个线程间的一种协作机制。谈到线程我们经常想到的是线程间的竞争(race),比如去争夺锁,但这并不是故事的全部,线程间也会有协作机制。就好比在公司里你和你的同事们,你们可能存在在晋升时的竞争,但更多时候你们更多是一起合作以完成某些任务。
就是在一个线程进行了规定操作后,就进入等待状态(wait()), 等待其他线程执行完他们的指定代码过后 再将其唤醒(notify());在有多个线程进行等待时, 如果需要,可以使用 notifyAll()来唤醒所有的等待线程。
wait/notify 就是线程间的一种协作机制。

等待唤醒中的方法
等待唤醒机制就是用于解决线程间通信的问题的,使用到的3个方法的含义如下:

调用wait和notify方法需要注意的细节

重点:有效的利用资源   
比如(生产一个包子,吃一个包子,再生产一个,再吃掉一个包子)


File类


抽象?abstract

我们可以使用File类的方法
    创建一个文件/文件夹
    删除文件/文件夹
    获取文件/文件夹
    判断文件/文件夹是否存在
    对文件夹进行遍历
    获取文件的大小

File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法

file:文件
    directory:文件夹/目录
    path:路径


文件绝对路径:d:\aaa\bbb.java
文件构造路径:d:\aaa\bbb.java
文件名称:bbb.java
文件长度:636字节

目录绝对路径:d:\aaa
目录构造路径:d:\aaa
目录名称:aaa
目录长度:4096


File类遍历(文件夹)目录功能
    - public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
    - public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。



- public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
    - public boolean delete() :删除由此File表示的文件或目录。
    - public boolean mkdir() :创建由此File表示的目录。
    - public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。

public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
创建文件的路径和名称在构造方法中给出(构造方法的参数)
返回值:布尔值
    true:文件不存在,创建文件,返回true
    false:文件存在,不会创建,返回false


File类判断功能的方法
        - public boolean exists() :此File表示的文件或目录是否实际存在。
        - public boolean isDirectory() :此File表示的是否为目录。
        - public boolean isFile() :此File表示的是否为文件。

        public boolean isDirectory() :此File表示的是否为目录。

/判断file文件或目录是否实际存在。存在的话就打印输出
if (file.exists()){
    System.out.println(file.isDirectory());//                false
System.out.println(file.exists());//                        true
System.out.println(file.isFile());//                        true
}

//判断file是否为目录。存在的话就打印输出
if (file.isDirectory()){
    System.out.println(file.isDirectory());//             false
System.out.println(file.exists());//                      true
System.out.println(file.isFile());//                      true
}

//判断file表示的是否为文件。是文件就打印输出
if (file.isFile()){
    System.out.println(file.isDirectory());//                false
System.out.println(file.exists());//                        true
System.out.println(file.isFile());//                        true
}

if (file.exists()){
//判断file是否为目录
if (file.isDirectory()){
//正确的话输出路径
System.out.println(file.getPath());
    }
//判断file表示的是否为文件
if (file.isFile()){
//正确的话输出文件名字
System.out.println(file.getName());
    }
}

路径:
绝对路径:是一个完整的路径
以盘符(c:,D:)开始的路径
c:\\a.txt           
C:\\Users\itcast\\IdeaProjects\\shungyuan\\123.txt
D:\\demo\\b.txt
相对路径:是一个简化的路径
相对指的是相对于当前项目的根目录(C:\\Users\itcast\\IdeaProjects\\shungyuan)
如果使用当前项目的根目录,路径可以简化书写
C:\\Users\itcast\\IdeaProjects\\shungyuan\\123.txt-->简化为: 123.txt(可以省略项目的根目录)
    注意:
        1.路径是不区分大小写
        2.路径中的文件名称分隔符windows使用反斜杠,反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠



递归:方法自己调用自己

- 递归的分类:
     - 递归分为两种,直接递归和间接递归。
     - 直接递归称为方法自身调用自己。
     - 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
   - 注意事项:
     - 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
     - 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
     - 构造方法,禁止递归
   递归的使用前提:
       当调用方法的时候,方法的主体不变,每次调用方法的参数不同,可以使用递归


在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
11157
       Exception in thread "main" java.lang.StackOverflowError
构造方法,禁止递归
    编译报错:构造方法是创建对象使用的,一直递归会导致内存中有无数多个对象,直接编译报错

IO流

输入流                                         输出流
字节流                        字节输入流                                字节输出流
InputStream                                OutputStream
字符流                        字符输入流                                字符输出流
Reader                                        Writer


一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据

字节输出流【OutputStream】
FileOutputStream:文件字节输出流
作用:把内存中的数据写入到硬盘的文件中


FileOutputStream类
用于将数据写出到文件

数据追加续写  写出换行
Windows系统里,换行符号是\r\n

字节输入流【InputStream】读取文件的数据源
构造方法:
    FileInputStream(String name)
    FileInputStream(File file)
读取数据的原理(硬盘-->内存)
    java程序-->JVM-->OS-->OS读取数据的方法-->读取文件

字节输入流的使用步骤(重点):
    1.创建FileInputStream对象,构造方法中绑定要读取的数据源
    2.使用FileInputStream对象中的方法read,读取文件
    3.释放资源

重点
FileOutputStream
fos.close();
BufferedOutputStream
ObjectOutputStream
fis.close();






InputStreamReader类
InputStreamReader:是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。(解码:把看不懂的变成能看懂的)继承自父类的共性成员方法



使用InputStreamReader读取GBK格式的文件
使用InputStreamReader读取UTF-8格式的文件


OutputStreamWriter类
是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。(编码:把能看懂的变成看不懂)继续自父类的共性成员方法:
构造方法:
    OutputStreamWriter(OutputStream out)创建使用默认字符编码的 OutputStreamWriter。
    OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。
    参数:
        OutputStream out:字节输出流,可以用来写转换之后的字节到文件中
        String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8
使用步骤:
   
使用转换流OutputStreamWriter写GBK格式的文件
用转换流OutputStreamWriter写UTF-8格式的文件
1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
    2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
    3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
4.释放资源








字符缓冲输出流
字符缓冲输出流继承自父类的共性成员方法
构造方法:
    BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
    BufferedWriter(Writer out, int sz) 创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
    参数:
        Writer out:字符输出流
            我们可以传递FileWriter,缓冲流会给FileWriter增加一个缓冲区,提高FileWriter的写入效率
        int sz:指定缓冲区的大小,不写默认大小

特有的成员方法:
    void newLine() 写入一个行分隔符。会根据不同的操作系统,获取不同的行分隔符
    换行:换行符号
    windows:\r\n
    linux:/n
    mac:/r




字节缓冲输出流
字节缓冲输出流
构造方法:
    BufferedOutputStream(OutputStream out)  创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
    BufferedOutputStream(OutputStream out, int size)  创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。
    参数:
       OutputStream out:字节输出流
            我们可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高FileOutputStream的写入效率
       int size:指定缓冲流内部缓冲区的大小,不指定默认
使用步骤(重点)
    1.创建FileOutputStream对象,构造方法中绑定要输出的目的地
2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象对象,提高FileOutputStream对象效率
3.使用BufferedOutputStream对象中的方法write,把数据写入到内部缓冲区中
    4.使用BufferedOutputStream对象中的方法flush,把内部缓冲区中的数据,刷新到文件中
  5.释放资源(会先调用flush方法刷新数据,第4部可以省略)




字节缓冲输入流
字节缓冲输入流继承自父类的成员方法
构造方法:
    BufferedInputStream(InputStream in) 创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
    BufferedInputStream(InputStream in, int size) 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
    参数:
        InputStream in:字节输入流
            我们可以传递FileInputStream,缓冲流会给FileInputStream增加一个缓冲区,提高FileInputStream的读取效率
        int size:指定缓冲流内部缓冲区的大小,不指定默认

使用步骤(重点):
    1.创建FileInputStream对象,构造方法中绑定要读取的数据源
    2.创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率
    3.使用BufferedInputStream对象中的方法read,读取文件
存储每次读取的数据
记录每次读取的有效字节个数
    4.释放资源











欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2