android interview 2

这里介绍和java关联比较大的知识

类加载机制

java的类加载机制
Java 程序启动的时候,并不会一次性加载程序中所有的 .class 文件,而是在程序的运行过程中,动态地加载相应的类到内存中。
通常情况下,Java 程序中的 .class 文件会在以下 2 种情况下被 ClassLoader 主动加载到内存中:

  1. 调用类构造器
  2. 调用类中的静态(static)变量或者静态方法

JVM 中自带 3 个类加载器:

  1. 启动类加载器 BootstrapClassLoader
  2. 扩展类加载器 ExtClassLoader (JDK 1.9 之后,改名为 PlatformClassLoader)
  3. 系统加载器 APPClassLoader

双亲委派模式

所谓双亲委派模式就是,当类加载器收到加载类或资源的请求时,通常都是先委托给父类加载器加载,父类为null,则使用BootstrapClassLoader.也就是说,只有当父类加载器找不到指定类或资源时,自身才会执行实际的类加载过程。

为什么要有双亲委派策略
因为java虚拟机,使用不同的类加载器,加载同一个.class会认为是不同的类,为了保障java运行时,系统类正常加载,采用双亲委派策略

Android 中的ClassLoader
在 Android 虚拟机里是无法直接运行 .class 文件的,Android 会将所有的 .class 文件转换成一个 .dex 文件,并且 Android 将加载 .dex 文件的实现封装在 BaseDexClassLoader 中,而我们一般只使用它的两个子类:PathClassLoaderDexClassLoader

参考资料
深入理解 ClassLoader 的加载机制

java内存模型

它所描述的是多线程并发、CPU 缓存等方面的内容,这里需要注意不要将 JVM 内存结构混淆。

高速缓存产生的问题。每个处理器都有自己的高速缓存,同时又共同操作同一块主内存,当多个处理器同时操作主内存时,可能导致数据不一致,产生缓存一致性问题。
指令重排产生的问题。

内存模型是一套共享内存系统中多线程读写操作行为的规范,这套规范屏蔽了底层各种硬件和操作系统的内存访问差异,解决了 CPU 多级缓存CPU 优化指令重排等导致的内存访问问题,从而保证 Java 程序(尤其是多线程程序)在各种平台下对内存的访问效果一致。
在这套规范中,有一个非常重要的规则——happens-before

  • 程序次序规则
  • 锁定规则
  • 变量规则
  • 线程启动规则
  • 线程中断规则
  • 线程终结规则

使用 volatile 修饰 变量,使用synchronized关键字修饰操作都可以使 操作符合 happens-before 原则。

另外,volatile可以保证线程对变量访问的可见性(多线程异步满足可见性 有序性 原子性)

参考资料
Java 内存模型与线程

java锁

synchronizedReentrantLock
synchronized 使用更简单,加锁和释放锁都是由虚拟机自动完成。 ReentrantLock 需要开发者手动去完成。但是 ReentrantLock 的使用场景更多,公平锁 读写锁都可以在复杂场景中发挥重要作用。
ReentrantLock基本用法。
可以通过构造函数创建公平锁

public class ReentrantLockTest {
	ReentrantLock lock = new ReentrantLock();

	public static void main(String[] args) {
		ReentrantLockTest ll = new ReentrantLockTest();
		Thread t1 = new Thread(new Runnable(){
			@Override
			public void run(){
				ll.printLog();
			}
		})
		Thread t2 = new Thread(new Runnable(){
			@Override
			public void run(){
				ll.printLog();
			}
		});
		t1.start();
		t2.start();
	}
	public void printLog(){
		try{
			//加锁
			lock.lock();
			for(int i=0; i<5; i++){
				System.out.println(Thread.currentThread().getName() + "is printing "+i);
			}
		} catch(Exception e) {
		} finally {
			//手动释放锁,注意异常情况也要保障锁释放
			lock.unlock();
		}
	}
}

读写锁的基本用法

public class LockTest {
	//创建读写锁
	ReadWriteLock rwLock = new ReentrantReadWriteLock();
	//获取读锁和写锁
	ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
	ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();

	public void read() {
		readLock.lock()
		try {
			//从缓存中读取数据
		} finally {
			//要手动释放锁
			readLock.unlock();
		}
	}
	
	public void write(){
		writeLock.lock()
		try {
			//向缓存中写入数据
		} finally {
			//要手动释放锁
			writeLock.unlock();
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值