java 网络编程
socket
- Socket(套接字),封装了了TCP协议的通讯细节,是我们可以通过它,与网络建立连接
ServerSocket
- 是在服务端运行,有两个作用,想服务器申请端口,然后客户端 的Socket 通过这个端口与服务端建立连接
- 监听服务器端口,一旦一个客户通过该端口建立连接会自动创建一个Socket,然后通过这个Socket和客户端进行数据交互。(端口的取值范围是0-65535之间)
- serverSocket.accept();是一个阻塞方法,大应用方法后“卡主”,等待客户连接
Socket 两个重要方法
-
OutputStream getOutputStream()
该方法会获取一个字节输出流,通过这个输出流写出的字节数据会通过网络发送给对方。 -
InputStream getInputStream()
通过该方法获取的字节输入流读取的是远端计算机发送过来的数据。
多线程
- 线程:一个顺序的单一的程序执行流程,就是一个线程。代码一句一句的有先右后的顺序执行。
- 多线程:多个单一顺序执行的流程并发运行
- 并发: 事实上多个线程的运行是走走停停的,当线程运行时调度CPU,程序会将CPU运行时间划分为若干个时间片,在这个时间片内线程被执行,若果超时的话,CPU会在分配一个时间片给他,但是这个期间,已经执行过其他的线程了,但是因为CPU的执行时间是纳米级的,我们感受不到线程的切换,所以感觉上是并发执行的
- 线程的生命周期
[外链图片转存中…(img-3e0L5gl5-1660363263400)]
创建线程的两种方式
方式一 :
继承Thread 并重写run方法,但是启动线程的方法是start,而不是run 。这种方法的
- 优点是,结构简单,便于匿名内部类形式创建。
- 缺点是:
1.直接继承线程,会导致不能继承其他类去复用方法,这在实际开发中非常的不方便。
2.定义线程的时候重写了run方法,线程和线程任务绑定在一起了,不利于线程重用
方式二:
实现Runnable接口单独定义线程任务(ps:Runnable可以使用lambda表达式创建)
-
优点:实现接口没有继承冲突问题,线程与任务没有耦合关系,便于线程重用
Java中的代码都是考线程运行的,main方法也不例外,成为主线程 -
static Thread currentThread()该方法可以获取到这个方法的线程
线程API
- currentThread 获取主线程
- getName 获取线程的名字
- getId 获取该线程的唯一标识
- getPriority 获取该线程的优先级
- isAlive 该线程是否或者
- isDaemon 是否守护线程
- IsInterrupted 是否被中断了
线程优先级
线程start后会纳入到线程调度器中统一管理,只能被动的被分配时间片并发运行,而无法主动索取时间片,线程调度器尽可能均匀的将时间片分配给每一个线程
- 线程的优先级可以分为10级,1-10,5为默认值,优先级越高的线程获取时间片的次数越多,反之越少
- 优先级越高的线程获取时间片的次数越多。可以使用Thread的常量MIN_PRIORITY,NORM_PRIORITY,MAX_PRIORITY。他们分别表示 最低,默认,最高优先级
sleep阻塞(静态方法)
作用是是该方法的线程进入阻塞状态指定的毫秒,超时后会自动回到RUNNABLE状态再次获取时间片并发运行
sleep方法处理异常:InterruptedException.
当一个线程调用sleep方法处于睡眠阻塞的过程中,该线程的interrupt()方法被调用时,sleep方法会抛出该异常从而打断睡眠阻塞.
守护线程(后台线程)
- 通过是有普通线程调用setDaemon方法设置而来的,因此创建上与与普通线程无异
- 但是结束时机上有一点与普通线程不同,进程的结束
- 当一个进程中所有的普通线程都结束时,继承就会结束,此时会杀掉所有证在运行的守护线程
多线程并发安全问题
当多个线程并发操作同一临界资源,由于线程切换时机不确定,导致操作临界资源的顺序出现混乱严重时可能导致系统瘫痪.
临界资源:操作该资源的全过程同时只能被单个线程完成.
同步与异步的概念:同步和异步都是说的多线程的执行方式。
多线程各自执行各自的就是异步执行,而多线程执行出现了先后顺序进行就是同步执行
synchronized关键字
- 在方法上修饰,此时改变该方法变为一个同步方法
- 同步块,可以更准确的所动需要排队的代码片段
同步方法
当一个方法使用synchronized修饰后,该方法成为“同步方法”,即:多个线程不能同时在方法内部执行.只能有先后顺序的一个一个进行. 将并发操作同一临界资源的过程改为同步执行就可以有效的解决并发安全问题.
同步块
有效的缩小同步范围可以在保证并发安全的前提下尽可能的提高并发效率.同步块可以更准确的控制需要多个线程排队执行的代码片段.
语法:
synchronized(同步监视器对象){
需要多线程同步执行的代码片段
}
同步监视器对象即上锁的对象,要想保证同步块中的代码被多个线程同步运行,则要求多个线程看到的同步监视器对象是同一个.
静态方法上使用synchronized
当在静态方法上使用synchronized后,该方法是一个同步方法.由于静态方法所属类,所以一定具有同步效果.
静态方法使用的同步监视器对象为当前类的类对象(Class的实例)
静态方法中使用同步块时,指定的锁对象通常也是当前类的类对象
同步监视器对象的选取:
对于同步的成员方法而言,同步监视器对象不可指定,只能是this
对于同步的静态方法而言,同步监视器对象也不可指定,只能是类对象
对于同步块而言,需要自行指定同步监视器对象,选取原则:
1.必须是引用类型
2.多个需要同步执行该同步块的线程看到的该对象必须是同一个
互斥锁
当多个线程执行不同的代码片段,但是这些代码片段之间不能同时运行时就要设置为互斥的.
使用synchronized锁定多个代码片段,并且指定的同步监视器是同一个时,这些代码片段之间就是互斥的.