并发编程
1.进程和线程
进程:PC机上面正在运行的某个程序;
线程:进程中程序的一个执行过程;一个进程中至少有一个线程;
多线程:实现方式
继承 Thread 类
实现 Runnable 接口
无论什么方式实现:都必须重写 run方法;
如果要作为独立的线程来启动不是调用run()方法, 而是调用start()方法;
Thread.currentThread() 该方法获得线程;
多线程对同一个对象进行操作的时候一定要加锁; synchronized相当于对一个代码块加锁
synchronized必须定义一个锁旗标; 可以加在方法上面 旗标为this
Object lock = new Object();
2.sleep()线程休眠; 参数传递时间 单位ms
放弃对Cpu的抢占;,虽然放弃对cpu的抢占权,兵没有释放对锁旗标的控制权;
3.线程等待
wait() 是线程进入等待状态,和sleep()不同的是,sleep()是线程的方法, wait()是Object方法
任何对象都有wait()方法; 但是不是任何对象都能随便来调用wait()方法的
wait() 必须和 Suynchronized 搭配使用, 只有锁旗标调用wait()才不会报错;sleep()释放了cpu的抢占权 但是不会释放对锁的控制权, wait() 会同时释放对锁的控制权;
唤醒wait()状态线程的方法 由另一个线程
notify()唤醒wait() 的时候 有可能造成死锁; (所以线程都在等待状态,没有一条活跃的线程可以进行notify)
解决死锁的方式:
1.设置一个wait()的时间;
2.notifyAll();如果有多条wait线程 全部唤醒 wait中的线程;
4.线程池(ThreadPoolExecutor)
线程池主要解决两个问题,一方面是当执行大量的异步任务的时候,线程池能够提供较好的性能,这是因为使用线程池可以使每个任务的调度开销减少(线程池是可以复用的),另一方面,线程池提供了一种资源限制和管理的手段.,可以对执行的一系列线程进行管理
5.线程状态
a 新建(new):新建一个线程
b.可运行()
c.运行()
d.阻塞状态 sleep wait notify
e.死亡
IO流
1.在java中对于数据的输入\输出 以流(stream)的方式进行,
2分类 io包中定义了多个流类型(类或者抽象类)
按数据流的方向不同可以分为,输入流可输出流
按处理数据单位的不同可以分为字节流和字符流(只有文本文件可以使用)
按功能不同可以分为节点流和处理流
节点流可以从一个特定的数据源输入程序
处理流可以从多根管道处理过后的数据输入程序;
字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer
继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(8bit)
3.方法:
read();读取一个字节兵返回
read(byte[] buffer)读取一系列字节并存储到一个数组buffer中
read(byte[] buffer,int offset,int length);读取length个字节;
write(int b);向输出流写入一个字节数据;
wtite(byte [] b);奖一个字节类型的数组中的数据写入输出流
close()关闭流释放内存资源
flush();奖输出流中缓冲的数据全部写到目的地;
BufferedReader 传一个字符流,生成一个字符流(更高级)可以按行来读取;
4.节点流:
类型 字符流 字节流
File FileReader FileInputStream
FileWriter FileOutputStream
Memory Array CharArrayReader ByteArrayInputStream
CharArrayWriter ByteArrayOutoutStream
Memory String StringReader
StringWriter
Pipe(管道) PipedReader PipedInputStream
PipedWriter PipedOutStream
5.处理流:
缓冲流要套接在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
缓冲输入流支持父类的mark和reset方法
BufferedReader提供了readLine方法用语读取一行字符串(一\r或者\n分割)
BufferedWriter提供了newLine用语写入一个行分隔符;
对于输出的缓冲流,写出的数据会现在内存中缓存,使用flush方法将会是内存中的数据立刻写出
6.TransformIO转换流:
将对象转换成字节流或者字符流,叫做序列化,如果字节流或者字符流转换成对象叫反序列化;
如果想要被序列化或者反序列化必须实现 serializable接口
InputStreamReader和OutputStreamWriter用字节数据到字符数据之间的转换;
InputStreamReader需要和InputStream "套接"
OutputStreamWriter 需要和OutputStream "套接"
7.数据流:
DataInputStream和DataOutputStream 分别继承自 InputStream 和OutputStream
8.对文件操作
File 该类只能获取到硬盘下面的某个文件或者文件夹的信息,读和写是不可以的;
exists()判断是不是存在某个文件夹;
isFile()判断是不是文件而不是文件夹;
getName()获取文件或者文件夹的名字;
getAbsolutePath();获取文件或者文件夹的绝对路径;
getParent();找到某个文件或者文件夹的父级路径;
length();获取文件的大小,单位是字节;
createNewFile();创建一个新的文件 有一个要求就是文件必须不存在;
mkdir();创建一个文件夹(目录)
mkdirs();递归创建一个多层目录的文件夹;
9.字符流和字节流的区别:
字节流:传递的单位是以字节为单位进行传递;
字符流:传递的单位是以一个2字节为以一个单位的unicode;
把字节数组转字符串 new String (字节数组)
把字符串转化为字节数组 String.getBytes();
FileOutputStream 文件输出流(字节流);构造方法中可以传一个确认是否是追加内容;
inputStreamReader();构造方法中传一个字节流转换成字符流;
BufferedReader()传一个字符流,生成一个字符流(更高级)可以按照行来读取;
网络编程
--1.与我们程序联系最为紧密的为传输协议层
--TCP(传输控制协议):打电话(面向连接,安全可靠) 缺点速度慢,如果要发送的信息非常中要,不能丢失任何一个数据,那就要用TCP
--UDP(用户数据报协议): 发电报,写信,发短信,(面向非连接,不安全,不可靠) 优点:速度快, 缺点:不安全,不可靠
--如果在发送信息的时候,速度和效率更重要的就使用UDP
--2.TCP的三次握手过程
--首先,客户端发送syn报文给服务端,进入syn_send状态
--然后,服务端收到SYN报文,回应一个SYN报文,进入SYN_RECV状态
--客户端接收到服务端的SYN报文,回应一个ACK报文,进入Established状态
三次握手完成之后,就可以建立连接,然后就可以传输数据了
--3.TCP中的---Socket套接字
--4.UDP套接字
--在UDP中并没有明确的区分服务端和客户端,即又是客户端又是服务端.
UDP必须先启动客户端,然后才是服务器.
--DatagramSocket 此类表示用来发送和接收数据包的套接字;