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. math对象和date对象

    math对象的函数方法,记住Math首字母要大写 console.log(Math.abs(-5)); //取绝对值 console.log(Math.ceil(1.1)); //向上取舍 conso ...

  2. vs 异常处理

    解决方法: 4.0 删除 C:/Windows/Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files 2..0 删除 C:/WINDOW ...

  3. css框模型

    元素的背景是内容.内边距和边框区的背景. css中:width 和 height 指的是内容区域的宽度和高度.增加内边距.边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸. bootstr ...

  4. libpcap报文解析: ipv4、ipv6(待优化)

    #include <string.h> #include <stdlib.h> #include <pcap.h> #include <netinet/in. ...

  5. Symantec System Recovery

    目的:备份系统,备份文件,裸机恢复,异机恢复等 工具:http://bbs.kafan.cn/thread-1800182-1-1.html 下载地址:http://pan.baidu.com/s/1 ...

  6. 020ARM家族

    1.名称:6410.2440.210.A8.ARM9.ARM11.armv7.ARMv6(v:vsersion) 芯片的名称:6410.210.2440都是属于芯片的名称,都是来自三星公司: ARM核 ...

  7. DirectDraw打造极速图形引擎(Alpha混合)

    显然DirectDraw是Windows下写2D图形程序的最好选择,虽然Direct3D也可以写,但是没DirectDraw简单方便,特别对于初学者,一来就接触那么多函数和参数总不是件愉快的事,所以我 ...

  8. backBarButtonItem 颜色/文字修改

    iOS7之后. 默认的返回按钮字体颜色是蓝色的, 显示内如是父VC(上一级界面)的title 如果要做修改, 可以通过下面的办法: 1. 修改字体颜色 (1) 在plist里面, 加上View con ...

  9. Run JavaScript on your PeopleSoft pages conditionally

    Here, PeopleCode sets the logic that determines when the JavaScript code will run. This is not as si ...

  10. 64位操作系统弹出"Failed to load the JNI shared library “E:/2000/Java/JDK6/bin/..jre/bin/client/jvm.dll”

    64位操作系统弹出"Failed to load the JNI shared library /..jre/bin/client/jvm.dll”,最大的可能就是jdk的版本问题.去你的C ...