A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lst168 初级黑马   /  2018-11-26 16:22  /  644 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

day07-day10JavaEE笔记整理
1、等待唤醒机制

wait和notify/notifyAll的执行原理:

wait:

线程不再活动,不再参与调用,进入wait set中,因此不会浪费CPU资源,也不会去竞争锁,这是的线程状态是"WAITTING",它还要等着别的线程执行"通知(notify)",让在锁对象上等待的线程从wait set中释放出来,重新进入调度队列(ready queue)中

notify/notifyAll:

哪怕只通知了一个等待的线程,被通知的线程也不能立即回复执行,因为它当初中断的地方是在同步代码块中,而此刻它已经不持有锁,所以它需要"再次尝试去获取锁"(很可能面临其他线程的竞争),成功后才能在当初调用wait()之后的地方回复执行

总结如下:

如果能获取锁,线程就从"WAITTING"状态变成"RUNNABLE"状态否则,从wait set出来,线程就从        "WAITTING"状态又变成"BLOCKED"状态

调用wait()和notify()需要注意的细节:

1、wait()与notify()必须要由"同一个锁对象"调用

因为对应的锁对象可以通过notify()唤醒使用同一个锁对象调用的wait()后的线程

2、wait()与notify()是属于Object类的方法

因为锁对象可以是任意对象,而任意对象的所属类都是继承了Object类的

3、wait()与notify()必须要在"同步代码块"或者"同步方法"中使用

因为必须通过所对象调用这2个方法

2、线程池

线程池的工作原理:

提前创建号多个线程对象,放在集合中,多个任务来了反复使用这些线程对象来执行

线程池的创建和执行步骤:

1、使用Executors的静态方法newFixedThreadPool(int nThread)创建线程池ExecutorService

2、创建一个任务类,实现Runnable接口,重写run()方法

3、调用ExcutorService对象的submit(Runnable task)方法,传递任务给线程池,执行任务。

4、调用ExcutorService对象的shutdown()方法,销毁线程池

// 创建线程池对象

ExecutorService es = Executors.newFixedThreadPool(2);

// 提交任务

RunnableImpl r = new RunnableImpl();  // 1个任务

es.submit(new RunnableImpl());

es.submit(new RunnableImpl());

es.submit(new RunnableImpl());

// 销毁线程池

es.shutdown();

3、Lambda表达式:

函数式接口:"有且仅有一个抽象方法的接口"

抽象方法:1、有方法体的方法"不算作"抽象方法,如默认方法,静态方法,私有方法

2、 如果一个抽象方法 与 java.lang.Object类中的方法 定义相同的, 也"不算作"抽象方法

省略原则:

1、参数列表:参数”类型“可以省略(a,b)->{}

2、参数列表:如果参数只有1个,则"类型"和"小括号"都可以省略a->sout(a)

3、一些代码:如果只有一条代码,则”大括号“,“returen”,”分号“都可以”一起省略“

Lambda表达式的使用前提:

1、Lambda只能用于接口,且"接口中有且仅有一个抽象方法"(函数式接口)

2、使用Lambda必须具有上下文推断

4、File类

绝对路径:以盘符开始的路径

相对路径:不以盘符开始的简化路径

注意事项:1、路径不区分大小写;2、路径一般写成字符串,而字符串中一个\是转义,所以要写两个\\

常用方法:String getAbsolutePath()、String getPath()、String getName()、long length()、boolean exists、boolean isDirectory、boolean isFile、boolean createNewFile、boolean delete、boolean mkdir()、boolean mkdirs()、String[] list()、File[] listFiles

5、递归

递归的注意事项:

1、递归要有限定条件(出口),保证递归能够停止,否则栈内存溢出

2、递归次数不能太多,否则栈内存溢出

3、构造方法不能递归

6、字节流

     常用方法:void close()、void flush() 、abstract void write(int b)、void write(byte[] b)、void write(byte[] b, int offset, int len)、FileOutputStream(String name)、FileOutputStream(File file)

构造方法的作用:

1、创建一个FileOutputStram对象

2、根据构造方法传递的路径,在磁盘上创建一个空文件("如果文件存在则会清空数据")

3、将创建的FileOutputStram对象指向这个磁盘文件

使用字节输出流写数据到文件的步骤:

1. 创建对象: 创建FileOutputStream对象, 构造方法中传递文件路径

2. 写入数据: 使用FileOutputStream对象调用 write(int b) 方法, 将字节写入文件

3. 释放资源: 使用FileOutputStream对象调用 close() 方法, 关闭流对象释放资源

FileOutputStream(String name, boolean append): 通过文件路径创建流, true可以续写

FileOutputStream(File file, boolean append): 通过File对象创建流, true可以续写

字节输出流:

构造方法的作用:

1、创建一个FileOutputStream对象       

2、根据构造方法传递的路径,在磁盘上创建一个空文件

3、将创建的FileOutputStream对象指向这个磁盘文件

字节输出流: 一次写一个字节到文件

1. 创建对象: 创建FileOutputStream对象, 构造方法中传递文件路径

2. 写入数据: 使用FileOutputStream对象调用 write(int b) 方法, 将字节写入文件

3. 释放资源: 使用FileOutputStream对象调用 close() 方法, 关闭流对象释放资源

字节输入流: 一次读取一个字节

FileInputStream读数据步骤:

1. 创建FileInputStream对象

2. 使用FileInputStream对象, 调用 int read() 方法, 一次读取一个byte

3. 释放资源

字符输出流: 一次写一个字符

1.创建FileWriter对象, 构造方法中绑定要写入数据的目的地

2.使用FileWriter中的方法 write(), 把数据写入到"内存缓冲区"中(字符转换为字节的过程)

3.使用FileWriter中的方法 flush(), 把内存缓冲区中的数据,"刷新到文件中"

4.释放资源 close() (会先把内存缓冲区中的数据刷新到文件中)

7、Properties

常用方法:Properties()、Object setProperty(String key, String value)、String getProperty(String key)、Set<String> stringPropertyNames()、void store(OutputStream out, String comments)、void store(Writer writer, String comments)、void load(InputStream inStream)、void load(Reader reader)

使用步骤:

1、创建Properties        集合对象,添加数据

2、创建字节/字符输出流对象,构造方法中绑定要输出的目的地

3、使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中储存

4、释放资源

Properties: load()

使用步骤:

        1.创建Properties集合对象

        2.使用Properties集合对象中的方法load读取保存键值对的文件

        3.遍历Properties集合

8、缓冲流

缓冲流的原理:

1、底层也是使用基本流来读写

2、但缓冲流内部定义了一个缓冲数组,在读的时候类似于我们一次读一个数组的方式,减少了磁盘操作次数,提高了程序效率

BufferedOutputStream使用步骤:

1.创建FileOutputStream对象, 构造方法中绑定要输出的目的地

2.创建BufferedOutputStream对象, 构造方法中传递FileOutputStream对象

3.使用BufferedOutputStream对象中的方法 write(), 把数据写入到内部缓冲区中

4.使用BufferedOutputStream对象中的方法 flush(), 把内部缓冲区中的数据,刷新到文件中

5.释放资源(会先调用flush方法刷新数据, 第4步可以省略)

BufferedInputStream使用步骤:

1.创建FileInputStream对象, 构造方法中绑定要读取的数据源

2.创建BufferedInputStream对象, 构造方法中传递FileInputStream对象

3.使用BufferedInputStream对象中的方法 read(), 读取文件

4.释放资源 close()

9、乱码问题

乱码原因: 读写编码不一致

        GBK文件中存储的是"你好"在GBK中对应的byte

        而IDEA中使用FileReader读取文件时, 是将byte按照UTF-8编码表查找字符, 结果找不到, 就显示了问号

serialVersionUID序列号的作用:

        序列化操作时, 会根据类生成一个默认的 serialVersionUID 属性, 写入到文件中.

        该版本号是根据类中成员计算出来的一个数值. 当类的成员发生改变时, 序列版本号也会发生变化

        当代码中的类和读取的对象序列版本号不一致时, 就会抛出InvalidClassException

10、打印流PrintStream:

PrintStream特点:

        1. 只有输出流, 没有输入流

        2. PrintStream不会抛出IOException

        3. 有特殊方法 print(), println(), 可以输出任意类型的值, 原样输出

注意事项:

        如果用 write(97) 方法, 会查编码表   97 -> a

        如果用 print(97), println(97), 则原样输出  97 int -> '9''7' -> byte -> 文件 97

        System.out.println();

        PrintStream out;





0 个回复

您需要登录后才可以回帖 登录 | 加入黑马