try catch
public static int getNum() { try { int a = 1 / 0; return 1; } catch (Exception e) { System.out.println("1");// int b = 2 / 0;//throw new Exception("asdasd"); System.out.println("2"); return 2; } finally { return 5; } }复制代码
总结: catch 中,遇到 return 或者再发生 catch ,将会直接执行 finally, 如果没有 finally 只有 再发生 catch 那就抛出异常。
toast :
这是因为Toast显示需要NotificationManagerService(查看Android源码)部分手机把通知权限关闭了,所以Toast无法正常弹出复制代码
线程问题:
1,wait 和 sleep 的区别
wait 会释放锁,sleep 会有持有锁。wait 用来线程间交互,sleep 用于暂停执行。复制代码
2,synchronized 和 volatile volatile:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改某个变量的值,这新值对于其他线程可见。(线程缓存无效,取主存中的值,具有原子性)2)禁止进行指令重排发散:1.原子性 i = 1 这种操作,i ++, j = i 都不是原子操作 2.可见性 Java就是利用volatile来提供可见性的。 当一个变量被volatile修饰时,那么对它的修改会立刻刷新到主存,当其它线程需要读取该变量时,会去内存中读取新值。而普通变量则不能保证这一点。 其实通过synchronized和Lock也能够保证可见性,线程在释放锁之前,会把共享变量值都刷回主存,但是synchronized和Lock的开销都更大。3.有序性 JMM是允许编译器和处理器对指令重排序的,但是规定了as-if-serial语义,即不管怎么重排序,程序的执行结果不能改变。 JMM保证了重排序不会影响到单线程的执行,但是在多线程中却容易出问题。 例子: 1,单例模式的实现,典型的双重检查锁定(DCL) 2,标记变量复制代码
3,线程池
1,线程池优势第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。 第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。2,线程池策略 a. 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务; b. 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列。 c. 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建线程运行这 个任务; d. 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常,告诉调用者“我不能再接受任务了”。 注意: 1、当一个线程完成任务时,它会从队列中取下一个任务来执行。 2、当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。复制代码
4,如何控制某个方法允许并发访问线程的个数
Semaphoresemaphore.acquire();semaphore.release();复制代码
5,反射
ava 中的反射首先是能够获取到 Java 中要反射类的字节码,获取字节码有三种方法, 1.Class.forName(className) 2.类名.class 3.this.getClass()。然后将字节码中的方法,变量,构造函数等映射 成相应的 Method、Filed、Constructor 等类,这些类提供了丰富的方法可以被我们所使用。1)动态代理复制代码
final Listlist = new ArrayList ();List proxyInstance = (List ) Proxy.newProxyInstance(list.getClass().getClassLoader(), list.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throwsThrowable {return method.invoke(list, args); }}); proxyInstance.add("你好"); System.out.println(list);复制代码
2)动态代理与静态代理的区别 静态代理通常只代理一个类,动态代理是代理一个接口下的多个实现类。 静态代理事先知道要代理的是什么,而动态代理不知道要代理什么东西,只有在运行时才知道。 动态代理是实现 JDK 里的 InvocationHandler 接口的 invoke 方法,但注意的是代理的是接口,也就是你的业务类必须要实现接口,通过 Proxy 里的 newProxyInstance 得到代理对象。还有一种动态代理 CGLIB,代理的是类,不需要业务类继承接口,通过派生的子类来实现代理。通过在运行时,动态修改字节码达到修改类的目的。AOP 编程就是基于动态代理实现的,比如著名的 Spring 框架、Hibernate 框架等等都是动态代理的使用例子。复制代码