15.网络联机
连接到外面的世界
聊天程序概述
- 客户端连接到服务器
- 服务器简历连接并把客户端加到来宾清单中
- 另外一个用户连接上来
- 用户A送出信息到聊天服务器上
- 服务器将信息送给所有的来宾
连接,传送与接收
建立socket连接
Tcp端口只是一个16位宽,用来识别服务器上特定程序的数字
一般0~1023保留给特定服务,1024~65535供自定义服务使用
要点
- 客户端与服务器的应用程序通过Socket连接来沟通
- Socket代表两个应用程序之间的连接,他们可能会是在不同的机器上执行的
- 客户端必须知道服务器应用程序的IP地址(或网域名称)和端口号
- TCP端口号是16位的值,用来指定特定的应用程序
- 从0~1023的端口号是保留给HTTP,FTP,SMTP等已知的服务.
- 客户端通过建立Socket来连接服务器
- 一旦建立了连接,客户端可以从socket取得底层串流
- 建立BufferedReader链接InputStreamReader与来自Socket的输入串流以读取服务器的文本数据
- InputStreamReader是个转换字节成字符串的桥梁,他主要是用来连接BufferedReader与底层的Socket输入串流
- 建立直接链接Socket输出串流的PrintWriter请求print()方法或println()方法来送出String给服务器
- 服务器可以使用ServerSocket来等待用户对特定端口的请求
- 当ServerSocket接到请求是,他会做一个Socket连接来接受客户端的请求
Java有多个线程但只有一个Thread类
有一个以上的执行空间代表什么
如何启动新的线程
- 建立Runnable对象
- 建立Thread对象(执行工人)并赋值Runnable(任务)
- 启动Thread
每个Thread需要一个任务来执行,一个可以放在执行空间的任务
实现Runnable接口来建立给thread运行的任务
建立线程的三个状态
- 新建
- 可执行
- 执行中
- 被挡住
线程调度器
没有API可以控制调度器,调度无法确定
####要点
- 以小写t描述的thread是个独立的线程
- Java中的每个线程都有独立的执行空间
- 大写T的Thread是java.lang.Thread这个类.他的对象是用来表示线程
- Thread需要做任务,任务是实现过Runnable的实例
- Runnable这个接口只有一个方法
- run()回事新县城所执行的第一项方法
- 要把Runnable传给Thread的构造函数才能启动新的线程
- 线程在初始化以后还没有调用start()之前处于新建立的状态
- 调用Thread对象的start()之后,会建立出新的执行空间,它处于可执行状态等待被挑出来执行
- 当Java虚拟机的调度器选择某个线程之后他就处于执行中的状态,单处理器的机器只能有一个执行中的线程
- 有时线程会因为某些原因而被阻塞
- 调度不能保证任何的执行时间和顺序,所以你不能期待他会完全地平均分配执行,你最多也只能影响sleep的最小保证时间
让线程小睡一下
Thread.sleep(2000);
使用sleep()让程序更加可预测
锁
synchronized 修饰方法
同步化的死亡阴影
死锁 deadlock 相互持有对方正在等待的东西
要点
- Thread.sleep()这个静态方法可以强制线程进入等待状态到过了设定时间为止
- 可以调用sleep()让所有线程都有机会运行
- sleep()方法可能会抛出InterruptedException异常,所以要包在try/catch块中,或者把它声明出来
- 可以用setName()给线程命名,通常是用来除错的
- 如果两个以上的线程存取堆上同一个对象可能会出现严重的问题
- 如果两个以上的线程存取堆上同一个对象可能会引发数据的损毁
- 要让对象在线程上有足够的安全性,就要判断出那些指令不能被分割执行
- 使用synchronized这个关键词修饰符可以防止两个线程同时进入同一对象的同一方法
- 每个对象都有单一的锁,单一的钥匙.这只会在对象带有同步化方法时才有实际的用途
- 线程尝试要进入同步化过的方法时必须要取得对象的钥匙,如果因为已经被别的线程拿走了,那就得等.
- 对象就算是有多个同步化过的方法,也还只有一个锁.一旦某个线程进入该对象的同步化方法,其他线程就无法进入该对象上的任何同步化线程.
- 本文链接: https://halo.cjh.kim/archives/headfirstjava15md
- 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!