head first java 笔记 chapter 14~15

来源:互联网 发布:mac用什么吉他声卡 编辑:程序博客网 时间:2024/05/19 18:17
Chapter 14序列化 文件的输入输出
序列化 serialization:被序列化的对象可以写入到文件中
序列化的文件比纯文本的文件更容易方程序恢复。

进行序列化时,被该对象引用的实例变量也会被序列化,且所有该对象中被引用的对象也会被序列化


实现序列化需要serializable接口,这个接口没有任何方法需要实现,只是用来声明实现它的类是可以序列化的
堆上的对象有状态(实例变量的值)序列化的对象保存了实例变量的值,可以还原出一样的实例。
可以通过标记某实例变量为transient表示不能被序列化,这样这个引用实例在序列化时会返回null;(静态变量不会被序列化)

假如父类不可以被序列化,在还原序列化子类时父类的构造函数会像创建新对象一样执行。也就是从第一个不可序列化的父类开始,全部都会重新初始状态


通过串流(stream)数据流实施序列化保存和恢复。例如
FileOutputStream fileStream = new FileOutputStream(“MyGame.ser”);//创建FileOutputStreamObjectOutputStream os = new ObjectOutputStream(fileStream);//创建ObjectOutputStreamos.writeObject(characterOne);//将引用的对象序列化并写入文件os.writeObject(characterTwo);os.writeObject(characterThree);os.close();//关闭ObjectOutputStream


串流需要两两链接:一个表示连接,一个用来调用方法;

串流代表来源与目的地之间的连接(文件、网络端口)

连接的串流通常是很底层的(FileOutputStream是写入字节的方法),按照对象层次的观点,需要高层的连接串流

注:输入输出相关操作需要在try catch块中进行

 

读取文本文件

缓冲区buffer,运用缓冲区能暂时存放数据,因为每次磁盘操作都比内存操作慢,用缓冲区可以暂时存下数据,存满是时写入磁盘。(writer.flush()强制缓冲区立即写入)

将BufferReader链接到FileReader或者将BufferWriter链接到FileWriter上


File类:代表磁盘上的文件,与文件内容无关,与路径有关,提供了一种比使用字符串文件名表示更安全的方式

 

注:存盘对话框:saveFile()


打开文件对话框:loadFile()

 

序列化的本本控制,serialVersionUID

对象被序列化时的类的版本识别ID,防止在还原序列化对象前修改了类。P460

 

Chapter 15网络与线程

Java.net库

传送与接收网络上的数据是链接上使用不同链接串流的I/O

客户端:需要知道谁是服务器

服务器:知道所有的客户端

Socket连接:建立socket链接代表两台机器存有对方信息,包括网络地址和TCP端口号。

TCP端口号是16位宽,用来识别应用程序的数字。0~1023是保留的


(客户端读取数据)链接到Socket上底层输入串流InputStreamReader(低层和高层串流间的桥梁);然后在用BufferReader从Socket上读取数据
 



(客户端发送数据)

直接建立链接到socket的PrintWriter


对于服务器应用程序,需要

1、等待用户请求(ServerSocket)   2、和用户通信用的Socket

对于服务器上的特定端口创建出ServerSocket

ServerSocketserverSock = new ServerSocket(4242);

当客户端对服务器上的应用程序建立Socket链接时,服务器创建与客户端通信的新Socket

Socket sock =serverSock.accept();

accept()在等待童虎的Socket连接时是闲置的,有用户连接上来时会返回一个不同端口上的Socket。这样能使Socket与ServerSocket占用的端口不同,ServerSocket可以空出来等待其他用户。



注:Socket类和 ServerSocket 类是Java 为 TCP 协议提供的。对于UDP协议,Java 通过 DatagramPacket 类和 DatagramSocket 类来使用 UDP 套接字,客户端和服务器端都通过DatagramSocket 的 send()方法和 receive()方法。由于 UDP 是无连接的,因此UDP服务端不需要等待客户端的请求以建立连接。另外,UDP服务器为所有通信使用同一套接字来发送和接收数据,用 DatagramPacket 来包装需要发送或者接收到的数据。

http://wiki.jikexueyuan.com/project/java-socket/udp.html

 

 

在信息发送到服务器上时就把它读回来,利用线程并行

线程Thread

在java.lang包中

一个新的线程有独立的执行空间(栈),建立新的线程对象就会启动新的线程

Thread类实现了Runnable接口(只有一个方法public void run()),线程的任务可以被定义到任何实现了Runnable的类上

Runnable threadJob= new MyRunnable();

Thread myThread =new Thread(threadJob);

myThread.start();//调用start()之后才会开始这个新线程,在这之前只是一个Thread实例,不是真正的线程

这样新线程启动后会把Runnable随想的方法摆到新的执行空间中。

 

多线程的情况下有一个以上的执行空间(栈)能快速来回交换(由JVM控制线程与原来主线程切换直到都完成),所有线程需要记录目前线程执行到哪了

 

线程调度器(操作系统)

线程的状态一般在可执行状态和执行中切换,有时会在阻塞状态

决不能让程序依靠调度的某种特定行为来保持正确,因为调度是用户无法控制的

可以调用sleep()方法使线程离开执行一段时间(ms)

 

线程不能重复使用,一旦run()方法完成后就会死掉,不能再被执行。

 

多线程会导致并发性(concurrency)引起竞争状态,导致数据的损毁。当两个或两个以上的线程存取单一对象的数据。

同步(synchronized)

让方法同步化,具有原子性(运行的过程中不会被其他线程打断)。关键字synchronized修饰的方法每次只能被单一的线程存取。

 

每个java对象都有一个锁,对应一把钥匙。当对象有同步化的方法时,线程只能在取得钥匙的情况下进入线程(没有其他线程已经进入的情况下)。也就是说对象的锁只会在有同步化的方法上起作用。

 

当对象有两个同步化方法时,不仅两个线程无法进入一个同步化方法,两个线程也不能同时进入任何同步化方法。

因为对象就算有多个同步化方法,但只有一个锁,一旦有线程进入该对象的同步化方法,对象就被锁上了,其他线程无法进入该对象上的任何同步化方法

 

注:同步化会增加额外成本,可能导致死锁现象(两个线程互相有对方等待的东西)。

数据库有时能处理死锁,有事物回滚机制。

Java没有处理死锁的机制。

 

同步化还可以不直接同步化全部方法:

 

当对静态变量进行同步化时,会使用类本身的锁


原创粉丝点击