MODULE 10 Threads 多线程
--------------------------------

进程: 计算机在运行过程中的任务单元,CPU在一个时间点上只能执行一个进程,但在一个时间段上采用时间分片原则。

特点:
每个进程执行时需要独立的数据空间,独立分配内存,多个进程间的资源互不共享。因此进程是非常耗费资源的

线程:是程序运行时的最小执行单位

特点:
1)线程依赖于进程
2)一个进程可以分为多个线程 例:QQ
3)*多线程可以共享资源

多进程和多线程的设计目的都是为了在同时执行多个任务

多线程带来的问题:
多线程间的并发(互斥)与同步,(由共享资源引发的问题)

线程类Thread

创建自己的线程
1.继承Thread类
class MyThread extends Thread{
public void run(){
//线程处理代码
}
}
运用:
MyThread th1=new MyThread();
th1.run();//错误
th1.start();//启动该线程,执行的是run()方法中的代码
2.实现Runnable接口
class MyThread implements Runnable{
public void run(){
//线程处理代码
}
}
运用:
MyThread th1=new MyThread();
th1.start();//错误
Thread thread=new Thread(th1);
thread.start();//启动线程,执行的是th1中的run()方法

练习:
龟兔猫狗百米赛跑,要求:只要有一个先跑到终点,比赛结束

分析:设置一个多个线程都共享的数据
static boolean isRunning=true;

线程生命周期的状态:
1.Runnable就绪状态
new -->start() --> Runnable
等待JVM调度执行
2.Running状态
JVM采取时间分片策略,被调度的线程从Runnable进入Running状态
执行run()方法中的代码,一旦时间片结束,无论run()方法是否执行完,JVM都会收回该线程的执行权,调度其他处于Runnable状态的线程
Runnable <-----> Running

3.Dead死亡状态
run()方法执行结束

4.Blocked阻塞状态
1)sleep() ---> blocked
等到睡眠时间结束,该线程从bloced ---> Runnable,等待JVM重新调度
2)join() ---> blocked
调用另一线程的join()方法,使本线程进入阻塞状态,直到另一线程执行结束,本线程 blocked ---> Runnable

多线程的并发访问
----------------------------------
多个线程共享数据引发并发问题

练习:

如何解决并发访问?
synchronized关键字
1)寻找公有的对象,并在公有对象身上加锁,确保一次只能有一个线程操作该对象
synchronized(Object){
//只允许一个线程执行这部分代码
}
2)精确控制加锁的范围(或者说加锁的临界值),否则影响程序效率

线程如何从locked回到Runnable状态
------------------------------------
1)sleep 睡眠时间结束,回到Runnable
2)join() 等到另一线程执行结束,本线程回到Runnable
3)如何人为使线程从blocked ------> Runnable
a) interrupt()
人为使线程从blocked ------> Runnable
阻塞的线程一旦被调用interrupt()方法唤醒,会抛出InterruptedException,线程自己可以通过捕获该异常知道自己被中断
b)isInterrupted() 返回boolean类型,判断线程是否被中断
c)interrupted() 清除中断信息,因为一个线程被中断后会设置标志信息,isInterruped()判断为true,一旦调用interrupted()清除中断信息后,isInterruped()判断改为false

练习:ThreadState.java , 在主线程中监控另一个线程让该线程sleep后,调用interrupt()方法使其从blocked回到Runnable

线程同步问题
-------------------------------------
并发:是多个线程地位均等,共同竞争对公有对象的访问权,一次只能一个线程访问

同步:解决的是多个线程对公有对象访问的先后顺序问题

解决同步问题的思路:
1)找出公有对象,多个线程都通过公有对象进行通信
2)找出哪个线程该wait,哪个线程负责notify发通知
3)确保wait在notify之前
添加标志变量hasWait,等待的线程在调用wait()之前设置该变量,负责发通知的线程在notify()之前先判断该变量,确保notify时公有对象身上已经有wait的线程

练习:
定义一个线程CalculateThread,计算1~100的和,把结果放到一个对象中
定义一个线程PrintThread,从该对象中取出结果并打印输出
定义一个测试程序Test.java

分析:
1)属于同步问题
2)公有对象Result{int value;}
3)CalculateThread负责notify,PrintThread负责wait

注意点:
1.wait()和notify()要加synchronized
多个线程竞争公有对象res的访问锁,等待的线程间要互斥
2.等待的线程在wait之前要先设置标志变量,否则wait之后阻塞,无法设置
3.发通知的线程在notify之前要循环判定公有对象身上是否有等待的线程,有wait线程才发通知唤醒
4.while循环一定要放synchronized外面,否则拿着锁再sleep,其他线程永远拿不到res对象的访问权

setPriority() 设置线程的优先级 1~10级 优先级并不能决定线程的先后执行顺序,最终仍由JVM决定

Thread.yield() 将执行权让给优先级比自己高的线程

弃而不用的方法:
stop() / resume() / suspend()
这些方法被调用时,线程所占据的资源的锁不会被释放

死锁问题
------------------------------
若干线程去竞争有限的资源,要求同时拿到多个公有资源时,因公有资源数量有限,不能满足所有线程的需求,每个线程都只拿到部分资源且不释放,就造成死锁问题

哲学家就餐问题

如何解决?
让多个竞争资源的线程以相同的顺序去拿

MODULE 11 I/O 输入/输出
------------------------------------
java中采取流的概念, 在应用程序和外围设备之间建立一个流对象,确保无论外围设备是什么,应用程序只单一的通过访问流对象来读写数据

按流的方向,分为:
输入流InputStream
程序从输入流【读取】数据,但不能写入
read()...
输出流OutputStream
程序往输出流中【写入】数据,但不能读取
write()...

按照流的传输单位
字节流
以字节为基本传输单位,一个个字节传输
注意点:
1)流中的数据没有结构,例int数据4个字节,拆成4次传输
2)最终传输给外围设备的一定是字节流
通常以Stream结尾的都是字节流*

字符流
字节的可读性很差,字符流提供以文本的形式读写数据
通常带有Reader/Writer的都是字符流*

具有缓存功能的流
在流对象中设置缓存区,数据先放入缓存区,再一次性读写外围设备
目的:提高数据的传输性能

过滤器
对流中提供的数据进行进一步处理
字节流传输无结构,过滤器可以将字节流中的字节拼成应用程序需要的数据类型,如int double float...
*不能单独使用,一定要结合某个字节流

InputStream常见的方法
read() 每次返回一个字节,返回结果>=0为有效数据, -1表示流中数据读完
read(byte[]) 可以一次读取多个字节,放入byte[]数组中,返回一次读取成功的字节数

注意:
I/O流要与外围设备进行交互,所有资源都要手工回收
finally{
//添加资源回收代码
}

close() 关闭流对象,释放内存资源
available() 判断流是否可用

flush() 程序强制将缓存区中的数据刷新到外围设备中

字节流的层级结构
-------------------------
通常InputStream/OutputStream 前面的代表了数据源或数据目的地类型
FileInputStream 把文件作为数据源,从文件中读数据
FileOutputStream 把文件作为数据目的地,往文件中写入数据

PipedInputStream 把管道作为数据源
PipedOutputStream 把管道作为数据目的地

过滤器 对字节流进一步包装
1)BufferedInputStream
具有缓存功能的流
2)PushbackInputStream
把从流中读取的数据退回去
3)DataInputStream
能够将字节流中的字节拼成程序需要的基本数据类型
readInt(0 readDouble()...

包: java.io;
异常: IOException

练习:创建类Copy.java实现文件的拷贝
将一个文件的内容拷贝到另一文件

分析:从源文件读入数据,FileInputStream read()
写入目标文件 FileOutputStream write()

改造:以提高性能的方式

例:以提高性能的方式从指定文件啊src.txt中读取含有基本数据类型的内容

分析:
DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream("src.txt")));

练习:将一个int型整数写入文件中
1)将一个个字节传输,将int拆成4个字节
2)DataOutputStream(BufferedOutputStream(FileOutputStream))

管道流PipedInputStream/PipedOutputStream
-----------------------------------------------
PipedInputStream 从管道中读取数据
PipedOutputStream 往管道中写入数据
通过管道将输入流和输出流衔接起来

练习:
创建两个线程,通过管道流实现两个线程的数据传输
一个线程Sender负责产生100个随机数,并写入管道中
一个线程Fetcher负责从管道中读取数据,并打印输出

分析; class Sender extends Thread{
PipedOutputStream pos;
public void run(){}
}
class Fetcher extends Thread{
PipedInputStream pis;
public void run(){}
}

字符流Reader/Writer
------------------------------
字节流可读性差,字符流提供以文本形式传输数据

特别的流对象
1.BufferedrReader/BufferedWriter
1)开辟缓存区提高传输性能
类似BufferedInputStream(BIS)/BOS
2)提供字符流和字符串之间的转换
类似DIS/DOS
BufferedReader: readLine() 字符流--->字符串
BUfferedWriter: write(String,off,len) 字符串---->字符流

2.InputStreamReader/OutputStreamWriter 桥梁类
最终与外围设备交互的是字节流
1)提供字节流和字符流之间的转换
InputStreamReader:字节流-----> 字符流
OutputstreamWriter:字符流----> 字节流
2)提供java标准编码UTF8和其他编码之间的转换

3.FileReader/FileWriter 是InputStreamReader/OutputStreamWriter的子类
1)具有读写文件的功能
2)作为ISR/OSW的子类,也提供字节流和字符流之间的转换
3)将编码自动转换成操作系统对应的编码格式

练习:
将一个字符串写入文件中,再读取该文件并将内容输出到控制台

分析:
字符串 --->文件
字符串----> 字符流 BuffredWriter
字符流 字节流 OutputStreamWriter FileWriter
字节流 文件 FileOutputStream
文件-----> 控制台

System.out 标准输出
System.in 键盘
System.err 标准错误

对象序列化 ObjectInputStream/ObjectOutputStream
------------------------------------------------------------
序列化:将对象转化为字节流,通常用于保存对象 的当前状态信息
使对象持久化,以备将来对该对象进行恢复
反序列化:字节流-----> Object

ObjectInputStream: Object readObject(){} 反序列化
ObjectOutputStream: writeObject(Object) 序列化

序列化实现接口:
Serializable

class Company implements Serializable{
String name;
int tel;
transient Address add; //标注该属性信息无法序列化
}
class Address{
String city;
String street;
int no;
}

注意:
1)大对象中包含小对象,序列化时要求小对象也实现了序列化接口
2)对于不能序列化的属性,需要用transient修饰

练习:ObjectTest.java

RandomAccessFile随机访问文件
-----------------------------------
以随机访问的方式读写文件中任意一段内容

skip(long) 虽是跳步,但也是从头开始跳过若干字节再进行读写

功能:
1)实现了DataInput / DataOutput接口,类似过滤器
2)读/写功能都具有
readInt() writeInt()......
3)具有操作文件的功能
4)可以随意跳到文件的某个位置开始读写

构造器中的参数:
mode 指定读/写的模式
"r":只读 "r":只写 "rw":读/写

seek(long) 跳过long 指定的若干字节数,开始读写

MODULE 12 Network网络编程
--------------------------------
ip地址 通过IP地址可以唯一定位到网络上的某台机器
port端口:人为制造的数字,代表一个服务器上某个应用的唯一标识

基于TCP/IP网络编程
传输控制协议,考虑的是传输的可靠性问题
基于UDP的网络编程
用户数据报文协议,考虑的是传输的效率问题

通讯双方满足的五要素:
1.通讯双方IP地址(两个)
2.通讯双方的PORT端口号(两个)
3.通讯双方要遵守同样的协议

java.net包:
Socket/SeverSocket:实现基于TCP/IP网络编程
DatagramSocket/DatagramPacket:为UDP协议服务

IP网络层
基本特点:
无连接的;数据可靠性不能保证的;

TCP 传输层
1)面向连接的
2)完全可靠的数据传输
3)点对点的
4)同一连接既可以发送也可以接收
5)面向字节流的

连接的简历经过了三次握手:
1)客户端发出连接请求
2)服务器回复确认
3)建立连接

Client:
构建Socket,连接指定的IP和port
---> 获取输入流/输出流
--> 对I/O流进行包装
---->读/写数据
-->释放资源(Socket/I/O)

Server:
构建SeverSocket,指定监听的端口号
--->接收客户端连接请求,获取Socket建立连接
----> 对I/O流进行包装
---->读/写数据
-->释放资源(sevrverSocket/Socket/I/O)

PrintWriter功能
String-->字节流
BufferedWriter 字符串-->字符流
OutputStreamWriter 字符流--->字节流
1.字符串--->字节流
兼具了BufferedWriter/OutputStreamWriter两者的功能
2.可以自动刷新
new PrintWriter(OS,true);

UDP 用户数据报文协议
-------------------------------------------
1)考虑的是数据传输的效率问题,可靠性不保证
2)不一定是一对一,而是多对多通讯,如广播
3)无连接的,不可靠的传输方式

DatagramSocket 负责数据的发送和接受 如邮递员
DatagramPacket 把数据打成报文对象,填入对方的IP地址和端口号 如信件

构造器:
DatagramPacket()

core java 10~12(多线程 & I/O & Network网络编程)的更多相关文章

  1. 20145221 《Java程序设计》实验报告五:网络编程及安全

    20145221 <Java程序设计>实验报告五:网络编程及安全 实验要求 掌握Socket程序的编写 运行TCP代码包,结对进行,一人服务器,一人客户端 掌握密码技术的使用 利用加解密代 ...

  2. mac 10.12 sierra 机械键盘+ratm可编程鼠标记录

      系统:mac 10.12 sierra 键盘:机械键盘 鼠标:mad catz ratm 在mac 10.11/10.12 之前: 机械键盘:一般的机械键盘在mac上使用, alt 和 win 键 ...

  3. 12篇学通C#网络编程

    转自:http://www.cnblogs.com/huangxincheng/archive/2012/01/03/2310779.html 在C#的网络编程中,进程和线程是必备的基础知识,同时也是 ...

  4. Java基础学习总结(18)——网络编程

    一.网络基础概念 首先理清一个概念:网络编程 != 网站编程,网络编程现在一般称为TCP/IP编程. 二.网络通信协议及接口 三.通信协议分层思想 四.参考模型 五.IP协议 每个人的电脑都有一个独一 ...

  5. [转]12篇学通C#网络编程——第二篇 HTTP应用编程(上)

    本文转自:http://www.cnblogs.com/huangxincheng/archive/2012/01/09/2316745.html 我们学习网络编程最熟悉的莫过于Http,好,我们就从 ...

  6. Java学习笔记【十二、网络编程】

    原计划的学习结束时间是3月4日,目前看来已经延迟了,距离低标还差一些,多方面原因,也不找借口,利用周末赶赶进度,争取本周末把低标完成吧! 参考: http://www.runoob.com/java/ ...

  7. Java程序设计学习笔记(六) — 网络编程

    时间:2016-5-8 02:03 --网络编程        网络传输实际上就是进行数据传输.    一.传输的步骤:        1.对对方IP地址进行定位.        2.将数据打包发送到 ...

  8. JAVA学习第五十九课 — 网络编程概述

    网络模型 OSI(Open System Interconnection)开放系统互连:參考模型 TCP/IP 网络通讯要素 IP地址 port号 传输协议 网络參考模型 七层OSI模型的基本概念要了 ...

  9. Java之旅_高级教程_网络编程

    摘自:http://www.runoob.com/java/java-networking.html JAVA网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. j ...

随机推荐

  1. Java学习一

    Java程序的运行机制和JVM     JVM(java 虚拟机) Java Virtual Machine java语言比较特殊,由Java语言编写的程序需要经过编译步骤, JDK java SE ...

  2. a different object with the same identifier value was already associat

    问题:这个著名的托管态update更新异常 org.hibernate.NonUniqueObjectException: a different object with the same ident ...

  3. WP8_给图片、按钮设置自定义图片

    工程目录下新建文件夹Images,将图片文件复制到Images文件夹里,本文以image1为例 1).在xaml里加背景图片 image图片: <Stretch="Fill" ...

  4. javascript 详解数组

      概念 数组创建 数组读写 数组 VS. 一般对象 相同点 不同点 稀疏数组 数组的length属性 元素增删 数组迭代 二维数组 数组方法 Array.prototype.join Array.p ...

  5. 第1部分: 游戏引擎介绍, 渲染和构造3D世界

    原文作者:Jake Simpson译者: 向海Email:GameWorldChina@myway.com ---------------------------------------------- ...

  6. C puzzles详解【51-57题】

    第五十一题 Write a C function which does the addition of two integers without using the '+' operator. You ...

  7. CSS: word-wrap和word-break

    最近修改页面排版的一些问题,发现关于内容分词换行有两个主要的CSS: word-wrap 和 word-break 特别是word-wrap还有个取值break-word,更使得这两个属性容易混淆. ...

  8. 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(五)-- Filter

    在上一篇里,介绍了中间件的相关内容和使用方法.本篇将介绍Asp.Net Core MVC框架的过滤器的相关内容和使用方法,并简单说明一下与中间件的区别. 第一部分.MVC框架内置过滤器 下图展示了As ...

  9. Application Designer Security

    This wiki page covers how to manage and restrict Application Designer security through permission li ...

  10. vue.js插件使用(01) vue-resource

    本文的主要内容如下: 介绍vue-resource的特点 介绍vue-resource的基本使用方法 基于this.$http的增删查改示例 基于this.$resource的增删查改示例 基于int ...