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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 社会人 初级黑马   /  2018-11-26 15:19  /  630 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

第七天
线程池通信等待唤醒机制
等待唤醒机制:    wait/notify, 就是"线程间的一种协作机制", 用于实现线程间通信
等待唤醒中的方法 java.lang.Object类:    // 成员方法 (只能通过"锁对象"调用)    void notify(): 随机唤醒在同一个锁对象上的某一个处于等待状态的线程    void notifyAll(): 唤醒所有在同一个锁对象上处于等待状态的线程    void wait(): 让当前线程处于无限等待状态, 同时释放锁        
wait和notify/notifyAll的执行原理:    wait:        线程不再活动, 不再参与调度, 进入 wait set 中, 因此不会浪费 CPU 资源, 也不会去竞争锁, 这时 的线程状态即是"WAITING". 它还要等着别的线程执行"通知(notify)", 让在锁对象上等待的线程从 wait set 中释放出来, 重新进入到调度队列(ready queue)中    notify/notifyAll:        哪怕只通知了一个等待的线程, 被通知线程也不能立即恢复执行, 因为它当初中断的地方是在同步块内, 而 此刻它已经不持有锁, 所以它需要"再次尝试去获取锁"(很可能面临其它线程的竞争), 成功后才能在当初调用 wait() 之后的地方恢复执行        总结如下:            如果能获取锁, 线程就从"WAITING"状态变成"RUNNABLE"状态            否则, 从 wait set 出来, 又进入entry set, 线程就从"WAITING"状态又变成"BLOCKED"状态
调用 wait() 和 notify() 需要注意的细节:    1. wait() 与 notify() 必须要由"同一个锁对象"调用        因为对应的锁对象可以通过 notify() 唤醒使用同一个锁对象调用的 wait() 后的线程    2. wait() 与 notify() 是属于Object类的方法        因为锁对象可以是任意对象, 而任意对象的所属类都是继承了Object类的    3. wait() 与 notify() 必须要在"同步代码块"或者是"同步方法"中使用        因为必须要通过锁对象调用这2个方法
线程池
普通创建线程方式的缺点:   
"创建"线程和"销毁"线程都是比较占用内存和CPU的操作.     对于一些数量多, 执行时间短的任务, 频繁的创建和销毁线程来执行, 会降低程序运行效率.     
线程池:   
一个容纳多个线程的容器(集合)   
线程池可以解决的问题:   
其中的线程可以反复使用, 省去了频繁创建线程对象的操作, 无需反复创建线程而消耗过多资源   
线程池的工作原理:   
提前创建好多个线程对象, 放在集合中. 多个任务来了反复使用这些线程对象来执行
public class RunnableImpl implements Runnable {    @Override    public void run() {        System.out.println(Thread.currentThread().getName() + "号柜台为您服务");        
System.out.println("顾客正在办理业务...");        
try {            Thread.sleep(2000);        
} catch (InterruptedException e) {
            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName() + "号柜台期待您再次光临");        
System.out.println("--------------------------------------------");   
}
}
public class Test {   
public static void main(String[] args) {        // 创建线程池        ExecutorService executorService = Executors.newFixedThreadPool(2);        // 提交10个任务        
for (int i = 0; i < 10; i++) {            
executorService.submit(new RunnableImpl());      
}        // 可以关闭也可以不关闭        executorService.shutdown();   
}
}
函数式编程思想:Lambda表达式冗余的Runnable代码
// 我们要通过Lambda表达式简化以下的代码
new Thread(new Runnable() {   
@Override   
public void run() {        // 要执行的代码才是重要的   }
}).start();
关键代码是: run()方法中要执行的任务 而其他代码都只是形式
Lambda更优写法
// 函数式编程的代码    new Thread( ()-> {            System.out.println(Thread.currentThread().getName() + "新线程创建了");      
}   
).start();
Lambda标准格式
Lambda表达式的3个部分:   
  • 一些参数 ()        接口中抽象方法的参数列表. 没参数就空着; 有参数就写, 多个参数用逗号分隔   
  • 一个箭头 ->        将参数传递给方法体   
  • 一段代码 {}        重写接口抽象方法的方法体

格式:    // 写成多行    (数据类型 变量名, 数据类型 变量名) -> {
一些重写方法的代
}
可以合并为一行代码;
Lambda重写的有参有返回值的方法
    Arrays.sort(arr, (Person o1, Person o2) -> {            
return o1.getAge() - o2.getAge();        
});
Lambda自定义接口,抽象方法有参有返回值
invokeCalc(120, 130, (int a, int b)->{
            return a + b;      
});
第八天
File类
构造方法
public File(String pathname) :
通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
public File(String parent, String child) :
从父路径名字符串和子路径名字符串创建新的 File实例。
public File(File parent, String child) :
从父抽象路径名和子路径名字符串创建新的 File实例。
常用方法
public String getAbsolutePath() :
返回此File的绝对路径名字符串。
public String getPath() :
将此File转换为路径名字符串。
public String getName() :
返回由此File表示的文件或目录的名称。
public long length() :
返回由此File表示的文件的长度。
绝对路径和相对路径
绝对路径:从盘符开始的路径,这是一个完整的路径。
相对路径:相对于项目目录的路径,这是一个便捷的路径,开发中经常使用。
判断功能的方法
public boolean exists() :此File表示的文件或目录是否实际存在。
public boolean isDirectory() :此File表示的是否为目录。 public boolean isFile() :此File表示的是否为文件。
创建删除功能的方法
public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete() :删除由此File表示的文件或目录。 public boolean mkdir() :创建由此File表示的目录。 public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。
目录的遍历
public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
递归
递归:指在当前方法内调用自己的这种现象。
递归的分类: 递归分为两种,直接递归和间接递归。 直接递归称为方法自身调用自己。 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
注意事项: 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。 构造方法,禁止递归
递归累加求和
计算1到n的和
public class DiGuiDemo {         public static void main(String[] args) {      使   
int num = 5;                    
int sum = getSum(num);                    
System.out.println(sum);                  
}           
public static int getSum(int num) {                    
if(num == 1){         
return 1;            
}        return num + getSum(num‐1);
}
}
第九天
字节流
根据数据的流向分为:输入流和输出流。输入流 :把数据从 其他设备 上读取到 内存 中的流。
输出流 :把数据从 内存 中写出到 其他设备 上的流。
格局数据的类型分为:字节流和字符流。字节流 :以字节为单位,读写数据的流。
字符流 :以字符为单位,读写数据的流。
字节输出流
public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输 出到此输出流。 public abstract void write(int b) :将指定的字节输出流。
FileOutputStream类
public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。 public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。 当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文 件,会清空这个文件的数据。
1.写出字节: write(int b) 方法,每次可以写出一个字节数据
2.写出字节数组: write(byte[] b) ,每次可以写出数组中的数据
3.写出指定长度字节数组: write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节
数据追加续写
ublic FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的 文件。 public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。 这两个构造方法,参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。 这样创建的输出流对象,就可以指定是否追加续写了,
字节输入流InputStream
public void close() :关闭此输入流并释放与此流相关联的任何系统资源。   
public abstract int read() : 从输入流读取数据的下一个字节。 public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
FileInputStream类
FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系 统中的 File对象 file命名。
FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件 系统中的路径名 name命名。
读取字节数据
  • 读取字节: read 方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1

字符流字符输入流Reader
public void close() :关闭此流并释放与此流相关联的任何系统资源。   
public int read() : 从输入流读取一个字符。 public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中
FileReader类
FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。  
FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
当你创建一个流对象时,必须传入一个文件路径。类似于FileInputStream 。
读取字符数据
读取字符: read 方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回 -1 ,循环读 取
使用字符数组读取: read(char[] cbuf) ,每次读取b的长度个字符到数组中,返回读取到的有效字符个数, 读取到末尾时,返回 -1
字符输出流Writer
void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
abstract  void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,off数组的开始索引,len 写的字符个数。
void write(String str) 写入字符串。
void write(String str, int off, int len) 写入字符串的某一部分,off
字符串的开始索引,len写的字符个 数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。
FileWriter类
FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。  
FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。 当你创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream。
写出字符: write(int b) 方法,每次可以写出一个字符数据
关闭和刷新
flush :刷新缓冲区,流对象可以继续使用。
close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了
写出字符数组 : write(char[] cbuf) 和write(char[] cbuf, int off, int len) ,每次可以写出字符数 组中的数据,用法类似FileOutputStream
写出字符串: write(String str) 和write(String str, int off, int len) ,每次可以写出字符串中的 数据,更为方便
续写和换行:操作类似于FileOutputStream
属性集 Properties类
构造:
public Properties() :创建一个空的属性列表
基本储存方法:
public Object setProperty(String key, String value) : 保存一对属性。 public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。 public Set<String> stringPropertyNames() :所有键的名称的集合。
第十天
缓冲流 缓冲字节输出流: BufferedOutputStream
字节缓冲流   
                        |_ BufferedInputStream     # 缓冲字节输入流                       |_ BufferedOutputStream    # 缓冲字节输出流
字符缓冲流   
                        |_ BufferedReader          # 缓冲字符输入流   
                        |_ BufferedWriter          # 缓冲字符输出流    java.io.BufferedOutputStream类: 缓冲字节输出流   
// 构造方法   
BufferedOutputStream(OutputStream out): 使用基本流创建一个缓冲字节输出流    BufferedOutputStream(OutputStream out, int size): 使用基本流创建一个缓冲字节输出流, 设置 缓冲区大小    BufferedOutputStream使用步骤:   
1.创建FileOutputStream对象, 构造方法中绑定要输出的目的地    2.创建BufferedOutputStream对象, 构造方法中传递FileOutputStream对象   
3.使用BufferedOutputStream对象中的方法 write(), 把数据写入到内部缓冲区中   
4.使用BufferedOutputStream对象中的方法 flush(), 把内部缓冲区中的数据,刷新到文件中   
5.释放资源(会先调用flush方法刷新数据, 第4步可以省略)            FileOutputStream fos = new FileOutputStream("文件路径");    BufferedOutputStream bos = new BufferedOutputStream(fos);   
bos.write("你好".getBytes());   
// bos.flush();  // 可以省略   
bos.close();
缓冲字节输入流: BufferedInputStream
java.io.BufferedInputStream类: 缓冲字节输入流   
// 构造方法   
BufferedInputStream(InputStream in): 使用基本流创建一个缓冲字节输入流   
BufferedInputStream(InputStream in, int size): 使用基本流创建一个缓冲字节输入流, 设置缓冲 区大小   
使用步骤:   
1.创建FileInputStream对象, 构造方法中绑定要读取的数据源   
2.创建BufferedInputStream对象, 构造方法中传递FileInputStream对象   
3.使用BufferedInputStream对象中的方法 read(), 读取文件   
4.释放资源 close()            FileInputStream fis = new FileInputStream("文件路径");   
BufferedInputStream bis = new BufferedInputStream(fis);    byte[] bytes = new byte[1024];   
int len;   
while ((len = bis.read(bytes)) != -1) {        System.out.println(new String(bytes, 0, len));   
}   
bis.close();
缓冲流的效率测试: 复制文件
基本流 一次读写一个字节      一个字节
基本流 一次读写一个字节数组   一个字节数组
缓冲流 一次读写一个字节      一个字节数组
缓冲流 一次读写一个字节数组   两个字节数组
缓冲流 + 一次读写一个字节数组 效率最高
缓冲字符输出流: BufferedWriter
// 构造方法    BufferedWriter(Writer out): 使用基本流创建一个缓冲字符输出流   
BufferedWriter(Writer out, int size): 使用基本流创建一个缓冲字符输出流, 设置缓冲区大小   
// 特有方法   
void newLine(): 写入一个换行符, 换行符自动根据当前系统确定
转换流 字符编码和字符集
编码: 字符 -> 字节  'a' -> 97 解码: 字节 -> 字符  97 -> 'a'
编码表: 字符和二进制数字的对应规则     
字符集和编码表: 字符集包含编码表   
ASCII字符集        
ASCII编码表      
ASCII扩展编码表   
ISO-8859-1字符集: Tomcat Web服务器程序        
Latin-1: 拉丁字符. 没有中文. 每个字符由1个byte组成    GB字符集
GB2312编码表: 每个字符由2个byte组成        
GBK编码表: 每个字符由2个byte组成        
GB18030编码表: 每个字符由1, 2, 4个byte组成   
Unicode字符集        
UTF-8: ASCII字符占1个byte, 拉丁字符占2个byte, 中文占3个byte, Unicode辅助字符占4个byte        
UTF-16        
UTF-32   
ANSI: 表示使用系统默认编码表
OutputStreamWriter类
  OutputStreamWriter(OutputStream out): 使用默认编码表创建转换流    OutputStreamWriter(OutputStream out, String charsetName): 使用指定编码表创建转换流
// 使用默认UTF-8 OutputStreamWriter o = new OutputStreamWriter(new FileOutputStream("a.txt")); o.write("dsfdsfdsaf")
// 使用指定的GBK OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"), "GBK");        osw.write("你") -> 查"GBK"码表 -> -1,-2 -> FileOutputStream -> a.txt文件         
写数据: 字符流 --------------------------> 字节流
序列化流对象流对象序列化流: ObjectOutputStream
// 构造方法   
ObjectOutputStream(OutputStream out)   
// 特有成员方法   
void writeObject(Object obj): 将对象写出   
// 创建对象输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.txt"));
// 写对象
Student s = new Student("小美女", 18); oos.writeObject(s); // 释放资源
oos.close();
注意:    被读写的对象的类必须实现"java.io.Serializable"接口, 否则会抛出"NotSerializableException"
对象反序列化流: ObjectInputStream
  // 构造方法   
ObjectInputStream(InputStream in)   
// 特有成员方法   
Object readObject(): 读取对象   
// 创建对象输入流
ObjectInputStream oos = new ObjectInputStream(new FileInputStream("student.txt"));
// 读对象
Object o = oos.readObject(); Student s = (Student)o; System.out.println(s);
// 释放资源 oos.close();
今日API
BufferedOutputStream(OutputStream out): 使用基本流创建一个缓冲字节输出流    BufferedOutputStream(OutputStream out, int size): 使用基本流创建一个缓冲字节输出流, 设置 缓冲区大小
java.io.BufferedInputStream类: 缓冲字节输入流   
// 构造方法   
BufferedInputStream(InputStream in): 使用基本流创建一个缓冲字节输入流   
BufferedInputStream(InputStream in, int size): 使用基本流创建一个缓冲字节输入流, 设置缓冲 区大小   
java.io.BufferedWriter类:   
// 构造方法   
BufferedWriter(Writer out): 使用基本流创建一个缓冲字符输出流   
BufferedWriter(Writer out, int size): 使用基本流创建一个缓冲字符输出流, 设置缓冲区大小   
// 特有方法   
void newLine(): 写入一个换行符, 换行符自动根据当前系统确定    java.io.BufferedReader类: 缓冲字符输入流   
// 构造方法    BufferedReader(Reader in): 使用基本流创建一个缓冲字符输入流   
BufferedReader(Reader in, int size): 使用基本流创建一个缓冲字符输入流, 设置缓冲区大小   
// 特有方法
    String readLine(): 一次读一行字符串, "不包含换行符". 读到文件末尾返回null   
java.io.OutputStreamWriter类: 输出转换流. 字符流通往字节流的桥梁   
// 构造方法
    OutputStreamWriter(OutputStream out): 使用默认编码表创建转换流    OutputStreamWriter(OutputStream out, String charsetName): 使用指定编码表创建转换流   
java.io.InputStreamReader类: 输入转换流. 字节流通往字符流的桥梁   
// 构造方法   
InputStreamReader(InputStream in): 使用默认编码表创建转换流   
InputStreamReader(InputStream in, String charsetName): 使用指定编码表创建转换流   
java.io.ObjectOutputStream类: 对象字节输出流   
// 构造方法   
ObjectOutputStream(OutputStream out)   
// 特有成员方法   
void writeObject(Object obj): 将对象写出    java.io.ObjectInputStream类: 对象字节输入流   
// 构造方法  
  ObjectInputStream(InputStream in)   
// 特有成员方法   
Object readObject(): 读取对象   
java.io.PrintStream类: 字节打印流    // 构造方法    PrintStream(File file): 创建字节打印流, 输出到一个文件    PrintStream(OutputStream out): 创建字节打印流, 输出到一个字节输出流   
PrintStream(String fileName): 创建字节打印流, 输出到一个文件路径    java.lang.System类:   
// 静态方法
    static void setOut(PrintStream out): 设置System.out的输出目的地为参数的打印流



0 个回复

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