Java基础中的一些知识点(一)

Java基础知识

  • Java对象的复制
  • Java序列化
  • Java线程
  • Java多线程同步
  • Java网络IO编程

1. Java对象的复制

对于Java语言来说,数据类型可以分为基本数据类型和引用类型,而数据复制操作针对不同的类型具有不同的含义。数据复制可以分为浅复制和深复制。
对于基本数据类型而言,深浅复制无差,但对于引用类型却有区别。浅复制,复制的是引用,即对象的地址或者引用,一旦原来对象的引用所指地址内的数据发生变化,复制后的对象也会随之变化。深复制,复制的是引用所指地址内的数据,复制后的对象不会随着原对象中数据的变化而变化。

2. Java序列化

  • 定义
    Java对象序列化是指将那些实现Serializable接口的对象转化成一个字节序列。序列化后可以弥补不同操作系统之间的差异。而反序列化是序列化的逆过程,将字节序列恢复成原对象。

  • 应用
    Java的远程方法调用(RMI)、JavaBean的序列化

  • 实现方式
    1、实现Serializable接口,该方法能够序列化对象的所有属性。
    2、实现ExternalSerializable接口,该方法可以自定义要序列化的属性。

  • 常用的序列协议

      - XML序列: 性能很差,冗余大。
      - Json: 过于冗余
      - Protobuf、Avro:这两种是目前比较优越的。
    
  • 注意点
    带static修饰的属性不会被序列化;对象的类名、属性(除方法)均会被序列化。

3. Java线程

  • 线程的实现方式

    Java中对线程的是实现方式有三种,如下所示:

    (1) 实现Runable接口,实现run()。示例代码如下:
    
public class MyThread1  implements Runnable{
    public void run(){
       //具体方法
       System.out.println("实现Runable接口");
    }

    public static void main(String[]args){
       MyThread1 mt=new MyThread1();
       Thread thread=new Thread(mt);//以类MyThread1 为参数实例化一个Thread类对象
       thread.start();//启动线程
    }
}    
(2) 继承Thread类,重写run()。
    public class MyThread2  extends Thread{
    public void run(){
       //具体方法
       System.out.println("继承Thread类");
    }

    public static void main(String[]args){
       MyThread2 mt=new MyThread2();
       mt.start();//启动线程
    }
} 

以上两种方法需要start()来启动线程,之后JVM将线程放入就绪队列,等到可运行时再执行run(),无返回值,也不会抛出异常。

(3)实现Callable接口,实现call(),该方法不常用。有返回值,会抛出异常。
  • 线程中start()和run()函数的区别
    start():用来启动线程,实现真正的多线程。调用start()之后,线程并不是马上执行,而是先进入就绪状态,一旦有空闲cpu,就会开始调用run()执行。
    run():该方法是Thread类的一个方法,并没有实现多线程。如果直接调用run(),只有主线程会被执行。

  • 注意点
    启动线程,并不一定要调用start()方法,可通过建立一个Handler对象handler,并调用post(Runnable r)方法,即handler.post(r)便可实现线程的启动,这一过程相当于在原线程内直接调用run()方法,并没有建立新的线程。

4. Java多线程同步

  • 多线程同步方法

    Java可以实现多线程同步的方式有多种,这里主要介绍下面几种:

    • 同步方法: 用Synchronized修饰方法,可以保护整个方法只能被当前线程访问。
    • 同步代码块: 用Synchronized修饰语句块。
    • 可见性(仅用于变量):用Volatile修饰变量,使得变量在发生变化时能够第一时间让所有其他线程知晓。不会阻塞其他线程,也不是原子操作,不能用于修饰final变量。
    • 可重入锁: 通过实现Lock接口的ReentrantLock类实现。同一线程外层函数获得锁之后,内层递归函数仍有获锁代码,但不会受到影响。
    • ThreadLocal:在本地创建线程变量,该变量的读写操作完全独立于其他线程操作,主要参考了“以空间换时间”的思想。
  • Synchronized和Lock的区别
    Synchronized属于隐式锁,适用于并发量较小情况,是在JVM层实现的,系统可以监控锁的释放。
    而Lock是显示锁,需要在加解锁处用代码指出lock()和unlock()(在finally处显示释放锁),适用于并发量较大情况。

  • Synchronized和Volatile异同
    同: 两者均为了保证多线程读写数据后数据的一致性。
    异: Synchronized会锁定所修饰的对象,只允许当前线程访问,其他需要访问该对象的线程被阻塞,保证了对象的可见性和原子性。
    Volatile是将所修饰的对象拷贝一份后进行读写操作,结束后立马更新主存中原对象,过程中并不会阻塞其他线程,只具有可见性,无原子性。另外,Volatile还可以防止指令重排,在单例模型中有应用。

5. Java网络IO编程

  1. 传统BIO:同步并阻塞服务器通信模式,一个客户端一个线程(一个连接一个线程),即每次客户端发出一个请求,服务器端通过独立的一个Acceptor线程负责管理,创建一个新线程来处理。适用于连接数目少且固定的架构。
  2. 伪异步I/O:用线程池管理Acceptor线程管理的线程,即服务器端可以用1个或N个线程来处理客户端的M个连接请求(M>>N),底层依旧是同步阻塞I/O。
  3. NIO:同步非阻塞服务器通信模式,一个请求一个线程,利用多路复用器Selector轮询,一个Selector可以处理成千上万个客户端连接。适用于连接数目多且连接时间较短的操作。如聊天服务器。
  4. AIO:异步非阻塞服务器通信模式,一个有效请求一个线程,无需启动线程,即先由操作系统完成I/O请求,再通知服务器,被动回调处理客户端的有效请求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值