动态代理与静态代理

代理是基本的设计模式之一,使用代理对象代替真实对象的方法调用,可以扩展真实对象某些方法的功能。 在 java 中又分为静态代理和动态代理, 先看静态代理: 静态代理 public class DynamicDemo { public static void main(String[] args) { /** * 静态代理示例 */ System.

Bean装配相关注解

@ComponentScan 启用组件扫描 默认扫描与配置类相同的包以及子包 如何扫描指定的包 @ComponentScan(“包名”) 扫描一组包: @ComponentScan(basePackages={"xxx","xxx"}) 这种两种方式都是传入字符串,无法方便的重构。因为我们的编辑器

maven完全依赖本地库

1.从可上网的外部电脑下载需要的jar包,自行传到内部电脑maven仓库对应文件夹,比如 com.alibaba.easyExcel,【注意有些包会有其他的依赖jar包,需要一同下载】 2.IDEA中添加

Callable与Future的应用

为什么需要 Callable 无论是继承 Thread 类,还是实现 Runnale 接口,或者使用线程池的 execute 方法去执行一个异步任务,都无法将这个任务的返回值带出来,以 Runnale 接口为例: /** * @since JDK1.0 */ @FunctionalInterface public interface Runnable { public abstract void run(); } 可以看到 run() 方法没有参数,没有返回值,没

并发编程之 ForkJoin 框架

什么是 Fork/Join 框架 Fork/Join 是从 java7 开始提供的并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务的结果,得到大任务结果的框架. 如下图: Fork/Join 的特性 ForJoinPool 不是为了替代 ExecutorService, 而是它的补充,在一些可分割的大任务场

idea配置和插件导入导出的方法

用idea工具自带的配置导入导出功能只能作用于配置文件,不能把插件也导出, 可以找到idea的配置目录,把配置目录覆盖的新的机器上,配置目录查找方法: 把该目录打包移动到新的机器上,用同样的方法找到新机器

定时任务和周期性任务线程池的应用及原理

在 线程池的应用 一文中,讲解了常见几种线程池的使用方法与差别,今天再深入学一下其中定时任务线程池的用法和原理。 定时任务线程池 public class User { public static void main(String[] args) { // 创建一个定时任务线程池 ScheduledExecutorService executor =Executors.newScheduledThreadPool(1); // 提交任务,1 秒后开始执行 executor.schedule(new

线程池原理

ThreadPoolExecute 使用示例 public class User { public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor(2,10,60, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(10)); for(int i =0 ;i < 20; i ++){ executor.execute(new Task(i)); } executor.shutdown(); } } class Task implements Runnable { int i; public Task(int i ) { this.i = i; } @Override public void run() { System.out.println(new Date() + ":"+ i + ":" + Thread.currentThread().getName()); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } 先使用构造方法生成一个线程池对象,然后使用 execute

线程池的应用与原理

java 中的线程 线程是调度 CPU 资源的最小单位,线程模型分为 KLT 模型与 ULT 模型,JVM 使用的 KLT 模 型,Java 线程与 OS 线程保持 1:1 的映射关系,也就是说有一个 java 线程也会在操作系统里有一个对应的线程。 Java 线程有多种生命状态 :

ArrayList和CopyOnWriteArrayList

ArrayList ArrayList 的保护机制 for(String str : list){ if(str.equals("123")){ list.remove(str); //抛出异常 } } 这里的 foreach 语法糖实际上调用了 ArrayList 的迭代器类。如下: 如果在开始迭代的时候数组中有 5 个元素,但是在迭代中移除了一个元素,数组实际上还有 4 个元素,但是还是会遍历第五个元

ConcurrentHashMap与HashTable

HashTable 是什么? 之前详细介绍过 HashMap 的原理,HashTable 与 HashMap 用法一样,都是 key-value 结构,底层的实现都差不多,最大的区别是, HashTable 是线程安全的,HashMap 不是线程安全的。 为什么需要线程安全? 我们知道,HashMa

HashMap底层原理

在 JDK 1.8 版本之前,HashMap 底层的数据结构是数组 + 链表,如下图: 在 1.8 及以后是数组 + 链表 + 红黑树 重要的几个变量 DEFAULT_INITIAL_CAPACITY = 1 « 4; Hash 表默认初始容量 MAXIMUM_CAPACITY = 1 « 30; 最大 Hash 表容量 DEFAULT_LOAD_FACTOR = 0.75f;默认加载因子 TREEIFY_THRESHOLD = 8;链表转

并发编程之Atomic和Unsafe魔法类

原子操作 原子(atom)本意是“不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为”不可被中断的一个或一系列操作” 。在多处理器上实现原子操作就变得有点复杂 处理器会保证基本内

并发编程之Semaphore和CountDownLatch的用法

Semaphore Semaphore 是信号量的意思,它的作用是控制访问特定资源的线程数目,底层依赖 AQS 的状态 State,是在生产当中比较常用的一个工具类。 可以理解为许可证,或者令牌。线程想要访问某部分资源时,必须先获取一个许可证,才能

并发编程AQS原理

JDK1.5以前只有synchronized同步锁,并且效率非常低,大神Doug Lea自己写了一套并发框架,这套框架的核心就在于AbstractQueuedSynchronizer类(即AQS),性能