11_21-11_25周总结

本文探讨了多线程的创建方法,包括自定义Runnable接口与Thread类的结合,Java设计模式中的静态代理与线程安全问题的校验。此外,讲解了Lock锁、线程池、Timer定时器和File的高级功能,以及IO流、递归算法、序列化等内容。
摘要由CSDN通过智能技术生成

11_21

1.多线程的创建方式

多线程的创建方式2:

)自定义一个类实现Runnable接口

2)实现接口里面的run方法--->完成耗时操作

3)在main用户线程中创建当前这个类的实例--->"资源类对象"

4)创建线程类Thread对象,然后将3)资源类对象 作为参数传递,启动线程!

2.Java设计模式 结构型设计--->代理模式--->静态代理
代理设计模式
        静态代理
        动态代理

代理设计模式

代理核心思想: 真实角色专注自己的事情(开发中,针对自己的业务) 代理角色帮助真实完成一件事情 静态代理: 代理角色和真实角色要实现同一个接口

动态代理:后面讲

jdk动态代理 cglib动态代理(需要导入cglib.jar包)

3.解决线程安全

校验多线程安全问题的标准 (使用标准来看多线程环境是否存在问题,以及解决方案)

1)是否是多线程环境 --->是

2)是否有共享数据 ---> 是存在的

3)是否有多条语句对共享数据操作

tickets票:多条语句同时操作

将3)多条语句多共享数据的操作使用同步代码块包起来---解决线程安全问题

synchronized(锁对象){ * 多条语句对共享数据操作 * }

锁对象:可以是任意Java类对象,但是多个线程必须使用的同一个锁对象,否则"锁不住"!

什么是同步方法(非静态)?如果一个方法中第一句话是一个同步代码块,可以将synchronized关键字定义在声明上

权限修饰符 synchronized 返回值类型 方法名(参数列表){

...

}

锁对象:this---代表类对象的地址值引用 * 如果是静态的同步方法,锁对象---->当前类名.class(字节码文件对象)

4.为什么wait()和notify(),线程等待,线程唤醒为什么定义Object类中?

这些方法都是和锁对象有关系,而锁对象可以是任意Java类对象,而定义Object类中

调用 wait(),会立即释放锁!

11_22

1.jdk5以后Lock锁(接口)---->ReetrantLock可重入的互斥锁

Lock这个接口

Lock实现提供比使用synchronized方法和语句可以获得的更广泛的锁定操作

实现类: 可重入的互斥锁 java.util.concurrent.locks.ReentrantLock

获取锁:指定的某个时刻 public void lock()

释放锁 : public void unlock() * Lock l = ...;

l.lock();

try {

// access the resource protected by this lock

} finally {

l.unlock(); //释放锁(系统相关的资源)

}

电影院三个窗口同时出售100张票,使用方式2实现---->昨天使用synchronized同步代码块或则同步方法使用Lock进行锁定的操作:获取锁,以及释放锁

2.创建线程的方式3: 线程池

线程池:

会创建一些固定的可重复使用的线程数,会在线程池中,循环利用

当某些线程使用完毕,不会被释放掉,而是归还连接池中,等待下一次再去利用!

成本比普通创建线程方式要大!

java.util.concurrent.Exceutors 工厂类

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定的可重复的线程数的线程池

java.util.concurrent ExecutorService ----->接口的具体实现类 public class ThreadPoolExecutor

<T> Future<T> submit(Callable<T> task):提交异步任务,返回值就是异步任务计算的结果;

上面这个的返回值Future :异步计算的结果---如果现在只是看多个线程是否能够并发的去强转CPU执行权,并没有返回结果

这个返回值可以不用返回!

Callable:接口---->异步任务的执行 类似于 之前Runnable接口

void shutdown():关闭线程池

3.Java提供了 Timer定时器----执行定时任务TimerTask

java.util.Timer:定时器(可以执行一次或者重复执行某个任务)

构造方法:

Timer():创建一个计时器

成员方法

public void cancel()取消定时器

void schedule(TimerTask task, Date time) :在给定的日期时间来执行TimerTask定时任务 --->

String dataStr = "2022-11-22 18:00" ;//---->日期文本---->java.util.Date

(应用场景:引入使用io流的方式,在指定时间点上,删除指定带内容的目录里面的所有.java文件)

void schedule(TimerTask task, long delay) :在给定多少毫秒后(延迟时间)执行这个定时任务 

public void schedule(TimerTask task,long delay,long period):在指定延迟时间(delay)执行任务,  然后每经过固定延迟时间(period)重复执行任务

schedule这些方法第一个参数都是定时任务:TimerTask是一个抽象类,

1)可以定义具体的子类继承自TimerTask

2)直接可以使用抽象类的匿名内部类

4.使用java.io.File来描述路径形式

File(File parent, String child)

File(String pathname) 推荐第二个

File(String parent, String child)

5.IO流

基本功能:

创建文件/文件夹

public boolean createNewFile()throws IOException:创建文件,如果不存在,创建,返回true

public boolean mkdir():创建文件夹,如果存在了,则返回false;否则true

public boolean mkdirs():创建多级目录,当父目录不存在的时候创建

判断

public boolean isFile():是否是文件 使用居多

public boolean isDirectory():是否是文件夹 使用居多

public boolean isAbsolute():是否为绝对路径

public boolean exists():判断文件或者目录是否存在

删除

public boolean delete():删除由此抽象路径名表示的文件或目录 (删除目录,目录必须为空)

11_23

1.java.io.File ----> 高级功能:获取指定目录下的所有的文件夹以及文件的Fiie数组

java.io.File:高级功能

public File[] listFiles():获取指定抽象路径表示下的所有的File数组

推荐---->使用File的功能进行判断

public String[] list():抽象路径名表示的目录中的文件和目录。

2.递归算法

递归: 方法调用本身的一种现象! 不是方法嵌套方法

方法递归:

1)需要有方法

2)有一定规律

3)有方法结束的条件(出口条件),否则 "死递归"

构造方法没有递归

3.IO流的分类 (输入流和输出流)

1)按流的方向划分

输入流 ---->读

输出流 ---->写

2)按流的类型划分--同时按方向划分:

字节流

字节输入流:InputStream--->不能实例化--->具体的子类:针对文件的字节输入流 FileInputStream

字节输出流:OutputStream--->不能实例化--->具体的子类:针对文件的字节输出流 FileOutputStream 字节缓冲流(字节高效流)

字节缓冲输入流:BufferedInputStream

字节缓冲输出流:BufferedInputStream

字符流

字符输入流

字符输出流

4.基本字节流

public FileOutputStream(String name,boolean append) throws FileNotFoundException

创建字节文件输出流对象,实现文件的末尾追加,而不将之前覆盖,第二个参数必须为true

IO流操作的时候,加入异常处理代码格式---->开发中 try...catch...finally 使用捕获一次

字节输入流:InputStream--->读 抽象类

提供子类:FileInputStream:针对文件操作的字节输入流

1)创建文件字节输入流对象

2)读文件

public int read() throws IOException:一次读取一个字节,返回字节数

public int read(byte[] b) throws IOException:一次读取一个字节数组

3)释放资源

11_24

1.BufferedInputStream/BufferedOutputStream:字节缓冲流

字节缓冲输出流/输入流 (高效字节流)

BuffedOutputStream/BufferedInputStream:只是提供一个字节缓冲区,本身就是一个字节数组,不会直接操作文件

操作具体的文件使用都是基本字节流FileInputStream/FileOutputStream

public BufferedOutputStream(OutputStream out):创建一个字节缓冲输出流对象,默认缓冲区大小(足够大)

public BufferedInputStream(InputStream in):创建一个字节缓冲输入流对象,默认缓冲大小

2.字符流 (针对字符操作)

字符流是在字节流后出现,如果是文本文本进行操作,优先使用字符流!

字符流

Writer:具体的子类

public OutputStreamWriter(OutputStream out):

字符转换输出流(可以将基本字节输出流转换成字符输出流),平台默认的字符集编码(idea,utf-8)

public OutputStreamWriter(OutputStream out,String charsetName):

字符转换输出流 ,指定一个编码字符集

写的功能

void write(char[] cbuf)写入一个字符数组。

abstract void write(char[] cbuf, int off, int len) 写入字符数组的一部分。

void write(int c) 写一个字符

void write(String str)写一个字符串

void write(String str, int off, int len) :写入字符串的一部分

Reader:抽象类

具体子类

public InputStreamReader(InputStream in):创建字符转换输入流,以平台默认字符集解码

public InputStreamReader(InputStream in,String charsetName):

创建字符转换输入流对象,指定字符集解码

read的功能 * public int read(char[] cbuf):读取字符数组

public int read():读一个字符

InputStreamReader/OutputStreamWriter:字符转换流弊端:代码格式复杂,不能直接操作文件!

3.字符缓冲流(使用居多)  + 集合  + 多线程 (综合使用)

BufferedReader(Reader in):字符缓冲输入流

也可以键盘录入

main()里面String[] 可以键盘录入 ,录入字符串

Scanner以及提供的nextXXX()

BufferedReader:字符缓冲输入流

BufferedWriter:字符缓冲输出流

他们不能直接操作文件,提供缓冲区让读写效率更高,特有方式

BufferedReader一次读取一行/可以作为键盘录入(录入一行字符串内容)

字符流针对文本文件(记事本打开能看懂的)-->字符流读写复制

1)字符转换流InputStreamReader/OutputStreamWriter 一次读取一个字符/一次读取一个字符数组

2)使用字符转换流的便捷类FileReader/FileWriter 可以直击操作文件 一次读取一个字符/一次读取一个字符数组

3)使用字符缓冲流BufferedReader/BufferedWriter: 一次读取一个字符/一次读取一个字符数组

4)使用字符缓冲流BufferedReader/BufferedWriter :一次读取一行特有方式(推荐!)读写复制

4.序列化ObjectOutputStream/反序列化ObjectInputStream

序列化:将一个Java对象(当前的类以及属性--->签名信息)--->"流数据" 前提条件就是 当前对象的所在类型必须实现java.io.serializable序列化接口---->实现了这个接口的类才能被序列化,产生固定serialVersionUID唯一的标识ID

序列化:ObjectOutputStream---->将java对象--->写到序列化流中

public ObjectOutputStream(OutputStream out)

反序列化:ObjectInputStream---->将序列化中流数据的信息---->还原成Java对象

11_25

1.java.util.Properties(很重要):属性列表集合类

Properties类表示一组持久的属性。

Properties可以保存到流中或从流中加载。(重要的地方)

属性列表中的每个键及其对应的值都是一个字符串。

继承Hashtable---->实现Map接口---->存储数据,取出数据----都可以使用Map的方式

构造方法:

public Properties():创建空的属性列表

java.util.Properites属性列表有自己的遍历方式---底层基于Map实现的

添加元素:

public Object setProperty(String key, String value)

遍历属性列表

public Set<String> stringPropertyNames()获取属性列表中的所有的键

public String getProperty(String key)使用此属性列表中指定的键搜索属性

Properties特有方式

public void load(Reader reader)throws IOException :

将指定文件中的内容加载属性集合列表中(内容键值对 key=value)

void store(Writer writer, String comments) :将属性列表中的内容保存指定文件中(以"键=值"元素对进行保存)

第一个参数:字符输出/使用字节输出流

第二个参数:属性列表的描述

相当于:

打游戏---->进度的加载

                 关卡的保存

2. 网络编程---(最终区别:TCP和UDP)

java.net.InetAddress:代表互联网ip地址对象

想获取计算机的主机名称或者获取计算机的ip地址字符串形式?

public static InetAddress getByName(String host) throws UnknownHostException

通过计算机主机名称或者是字符串形式的ip地址--->获取互联网ip地址对象

UDP接收端的代码实现

1)创建接收端的Socket对象,绑定端口

2)创建一个接收容器--->数据包--->自定义字节缓冲区,将发送的数据包

3)接收

4)从接收容器中解析数据包的实际内容数据

5)展示数据

Upd方式--->不需要建立连接通道,不可靠连接

Udp发送端的步骤

1)创建发送端的socket

2)创建数据报包

3)使用发送端的Socket将数据存储数据包中, 发送(本质存储数据包)

4)释放资源

先运行接收端,而且接收端不能运行多次,否则端口被占用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值