# 线程
#### 多线程原理
多个线程,竞争关系,互不影响
#### Thread类的常用方法
获取线程名称:
1.使用Thread类中方法getname()
String getName()返回该线程的名称
2.可以先获取当前正在执行的线程,使用线程中的方法getName()获取线程的名称
start Thread currentThread()返回当前正在执行的线程对象
线程名称:
主线程:main
新线程:Thread-0,Thread-1....
设置线程名称:
1.使用Thread类中的方法setName(名字)
void setName(String name)改变线程名称,使之与参数name相同
2.创建带参的构造方法,参数传递线程名称;调用父类的带参构造方法,
sleep方法:是当前正在执行的线程以指定的毫秒数暂停,毫秒执行之后继续执行
#### 创建线程第二种方式
实现Ruunnable接口
Runnable接口应该由那些打算通过们以线程执行其实列的类来实现。类必须定义一个称为run的无参数方法
实现步骤
1.创建一个Runnable接口的实现类
2.在实现类中重写run方法,设置线程任务
3.创建一个Runnable接口的实现类对象
4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
5.调用Thread类中的start方法,开始新的线程执行run方法
实现Runnable接口创建多线程程序的好处:
1.避免了单继承的局限性
一类只能继承一个类,类继承了Thread类就不能继承其他的类
2.增强了程序的扩展性,降低了程序的耦合性(解耦)
实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离
实现类中,重写了run方法:用来设置线程任务
创建Thread类对象,调用start方法:用来开启新的线程
#### 线程安全问题
#### 线程安全问题产生原理
开启3个线程,头t0,t1,t2,3个线程一起抢夺cpu的执行权,谁抢到谁执行
注意:线程安全问题是不能产生的,我们可以让线程在访问
#### 线程同步
1.同步代码块:
synchronized(锁对象){
可能出现线程安全问题的代码(访问了共享数据的代码)
}
注意:
1.通过代码块中的锁对象,可以使用任意的对象
2.但是必须保证多个线程使用的锁对象是同一个
3.锁对象的作用:
把同步代码块锁住,只让一个线程在同步代码块中执行
#### 同步技术原理
使用了一个锁对象,这个锁对象叫同步锁,也叫对象监视器
总结:同步中的线程没有执行完毕不会释放锁,同步外的线程没有锁进不去同步
同步保证了只能有一个线程咋同步执行共享数据
同步每次判断,效率降低
#### 同步方法
使用synchronized修饰的方法,就是同步方法
使用步骤:1.把访问了共享数据的代码抽取出来,放到一个方法中
2.在方法上添加synchronized修饰符
同步方法也会把符内部的代码锁住,只让一个线程执行,同步方法的锁对象就是实现类 对象也就是this
#### 静态同步方法:
锁对象不能是this,this是创建对象之后产生,今天方法优先于对象
静态方法的锁对象是本类的class属性-->class文件反射
#### Lock锁
Lock实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作
Lock接口中的方法:
Lock()获取锁
unLock()释放锁
使用步骤:1.在成员位置创建一个ReetrantLock对象
2.在可能会出现安全问题代码前调用Lock接口中的方法lock获取锁
3.在可能出现安全问题代码后调用Lock家口中方法unLock来释放锁
## 线程状态概述
wait,在其他线程调用此对象的notify方法或notifyAll方法前,导致当前线程等待
notify唤醒在此对象监视器上等待的单个线程
会继续执行wait方法之后的代码
进图到TimeWaiting(计时等待)
1.使用sleep(long m)方法,在毫秒值结束之后,线程醒来进入到Runnable/Blocked状态
2.使用wait(long m)方法,wait方法如果在毫秒值结束之后,还没有被notify唤醒,就会自动醒来,
3.notify只能换一个线程
4.notifyAll唤醒所有等待线程
# 线程池、Lambda表达式
#### 线程通信
概念:多个线程处理同一个资源,处理的动作(线程任务)不同
#### 等待唤醒机制
方法:
wait:线程不在活动,不在参与调度
notify:选取锁同一对象的wait set中的一个线程释放
notifyAll:释放所有同一对象
调用wait和notify方法需要注意的细节
1. wait方法与notify方法必须要由同一个锁对象调用。因为:对应的锁对象可以通过notify唤醒使用同一个锁对
象调用的wait方法后的线程。
2. wait方法与notify方法是属于Object类的方法的。因为:锁对象可以是任意对象,而任意对象的所属类都是继
承了Object类的。
3. wait方法与notify方法必须要在同步代码块或者是同步函数中使用。因为:必须要通过锁对象调用这2个方
法。
#### Lambda表达式
标准格式(无参无返回值)
Lambda表达式:时刻推导,可以省略
凡是根据上下文推导出来的内容,都可以省略书写
可以省略的内容:
1.(参数列表):括号中参数列表的数据类型,可以省略不写
2.(参数列表):括号中的参数如果只有一个,那么类型和()都可以省略
3.{一些代码}:如果{}中的代码只有一行,无论是否有返回值,都可以省略({},return,分号),
注意:要省略就一起省略
### 线程池
概念:
就是一个容纳多个线程的容器,其中线程可以反复使用,省去了频繁创建县城对象
当程序第一次启动的时候,创建多个线程,保存到一个集合当中,当我们想要使用线程的时候,就可以从集合中取出来线程使用
Thread t=list.remove(0)返回的是被移除的元素(线程只能被一个任务视同)
线程池:
Executors线程池的工厂类
类中静态方法
# File与递归
转义符 :\
#### 路径:
绝对路径:是一个完整的路径
以盘符开始的路径
相对路径:是一个简化的路径
相对指的是相对于当前项目的路径
注意:
1.路径是不区分大小写
2.路径中的文件称
#### File构造方法
File(String pathname) :通过将给定的**路径名字符串**转换为抽象路径名来创建新的 File实例。
参数:
String pathname :字符串的路径名称
路径可以是以文件结尾,也可以是以文件夹结尾
路径可以使相对路径,也可以是绝对路径
路径可以使存在,也可以不存在
只是把字符串路径封装为file对象,不考虑路径
File(String parent, String child) :从**父路径名字符串和子路径名字符串**创建新的 File实例
参数:路径分成了两部分
String parent:父路径
String child:子路径
好处:父路径和子路径,可以单独书写,使用起来非常李果;父路径和子路径都可以变化
public File(File parent, String child) :从**父抽象路径名和子路径名字符串**创建新的 File实例
参数:路径分成了两部分
File parent:父路径
String child:子路径
好处:
1.父路径和子路径,可以单独书写,使用起来非常李果;父路径和子路径都可以变化
2.父路径是File类型,可以使用file的方法对路径进行一些操作,在使用路劲创建对象
#### 判断功能方法
boolean exists() :此File表示的文件或目录是否实际存在
用于判断构造方法中的路径是否存在,
存在:true
不存在:false
public boolean isDirectory() :此File表示的是否为目录。
用于判断构造方法中给定的路径是否以文件夹结尾,是:true。否:false
public boolean isFile() :此File表示的是否为文件。
用于判断构造方法中给定的路径是否以文件结尾,是:true。否:false
注意:电脑的硬盘中只有文件/文件夹,两个方法互斥
这两个方法使用前提,路径必须是存在的,否则返回false
#### File创建和删除功能
public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
创建文件的路径和名称在构造方法中给出
注意:
1.此方法只能创建文件,不能创建文件夹
2.创建文件夹路径必须存在,否则会抛出异常
public boolean delete() :删除由此File表示的文件或目录。 可以删除构造方法中的路径文件/文件夹
注意:
delete方法是直接在硬盘删除文件/文件夹,不走回收站,文件夹有文件删不了,先删文件,在删文件夹
public boolean mkdir() :创建由此File表示的目录。
创建单级文件夹
public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录
既可以创建单级空文件夹,也可以多级文件夹,看类型是一个文件,不会哦爱出异常,路径存在,不会创建
总结:创建文件必须在已经存在的目录中创建,不会帮我们创建文件夹
删除文件夹,要先把文件夹里面的文件删除才能删除该文件夹...delete删除空文件夹
#### File遍历
public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
注意:
list和listFile方法遍历是构造方法中给出的目录,
如果构造方法中给出的目录的路径不存在,会抛出空指针异常
如果构造方法中给出的路径不是一个目录,也会抛出空指针异常
## 递归
递归:指当前方法内调用自己
分类:直接递归,间接递归
注意事项:
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
构造方法,禁止递归
编译报错:构造方法是创建对象是使用,每次调用参数不同
使用前提:调用方法的时候,方法的主体不变,每次调用方法的参数不同,可以使用递归
使用递归要明确:
1.递归的结束条件
2.递归目的
i:input输入(读取)
o:output输出(写入)
流:数据(字符字节)1个字符=2个字节 1个字节=8个二进制位
输入:把硬盘中的数据,读取到内存中使用
输出:把内存中的数据,写入到硬盘中保存
## 字节流
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) : 创建文件输出流以指定的名称写入文件。
参数:些人数据的目的地
String name:目的地都是一个文件的路径
File file:目的地是一个文件
作用:
1.创建一个FileOutputStream对象
2.会根据构造方法中传递的文件/文件路径,创建一个空的文件
3.会把FileOutputStream对象指向创建好的文件
**字节输出流的使用步骤:**
1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2.调用FileOutputStream对象中的方法write,把数据写入到文件中
3.释放资源
写数据的时候会把10进制的整数转换为2进制整数
#### 一次写多个字节的方法
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
如果写的第一个字节是整数,那么显示的时候回查询ASCII表
如果写一个的第一个字节是负数,那么第一个字节会和第二个字节,两个字节组成一个中文显示
public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输 出到此输出流。
int of:数组的开始索引
int len:写几个字节
写入字符串的方法:可以使用Sting类中的方法吧字符串,转换为字节数组
byte[] getByte()把字符串转换为字节数组
#### 追加写/续写:使用两个参数的构造方法
public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的 文件。
public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件
参数:String name ,File file:写入数据的目的地
boolean append:追加开关
true:创建对象不会覆盖源文件,继续在文件的末尾追加写数据
false:创建一个新的文件,覆盖源文件
## 字节输入流
定义了所有子类共性方法:
public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() : 从输入流读取数据的下一个字节。
public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中
FileInputStream:文件字节输入流
作用:把硬盘文件中的数据,读取到内存中使用
构造方法:
#### 读取数据原理(硬盘-->内存)
**字节输入流的使用步骤**:
1.创建FileInputStream对象,构造方法中绑定要读取的数据源
2.使用FileInputStream对象中的方法read,读取数据
3.释放资源
#### 一次读取多个字节
int read(byte[] b)从输入流读取一定数量字节,并将其存储在缓冲区数组中
明确两件事:
1.方法的参数byte[]的作用?
起到缓冲作用,存储每次读取到的多个字节
数组长度一般定义为1024(1kb)或者1024的整数倍
2.方法返回值int是什么?
读取的字节次数
文件复制,一读一写
明确:
数据源
数据目的地
# 字符流
Reader:字符输入流,是字符输入刘的最顶层的父类,定义了一些共性的成员方法,是一个抽象类
共性成员方法:
int read()读取单个字符返回
int read(char[] cbuf)一次读取多个字符,将字符读入数组
void class()关闭该流,释放所有资源
FileReader:文件字符输入流
作用:把硬盘文件中的数据已字符的方法读取到内存中
构造方法:
字符输入流作用:
1.创建FileReader对象,构造方法中绑定要读取的数据源
2,使用FileReader对象中的方法read读取文件
3.释放资源
FileWriter:文件字符输出流
作用:把内存中字符数据写入文件中
字符输出流的使用步骤:
1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
2,使用FileWriter中的方法write,把数据写入到内存缓冲区中
3.使用FileWriter中的方法flush,把内存缓冲区的的数据,刷新到文件中
4,释放资源(会先把内存缓冲区中的数据刷新到文件中)
#### flush方法和close区别
flush :刷新缓冲区,流对象可以继续使用。 close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了
#### try-catch-finally处理流中的异常
提高变量的作用域,让finally使用
变量在定义的时候,可以没有值,但是在使用的时候回必须有值
# Properties:
Properties类表示了一个持久的属性集,可保存在流中或从流中加载
唯一一个和IO流相结合的集合
可以使用Properties集合中的方法store,巴基和中的临时数据,持久化写入到硬盘存储
可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
属性列表中每个键及其对应的值都是一个字符串
Properties集合是一个双列集合,key和value默认都是字符串
#### Properties集合操作字符串的特有方法
public Object setProperty(String key, String value) : 保存一对属性。
public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
public Set<String> stringPropertyNames() :所有键的名称的集合。
可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
void load(InputSream inStream)
void load(Reader Reader)
参数:
InputSream inStream:字节输入楼,不能读取含有中文的键值对
Reader Reader:字符输入楼,能读取含有中文的键值对
使用步骤:
1.创建Properties集合对象
2.使用Properties集合对象中的方法load读取保存键值对的文件
3.遍历集合
注意:
1.存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)
2.存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
3.存储键值对的文件中,键与值默认都是字符串,不用再加引号
|
|