# 标签: 源码
当只有一个任务时,使用单个线程执行可以很好地满足需求;但由于单个线程是串行执行任务的,随着任务的增多,处理速度会很慢,如下代码:
java
List<Task> tasks = IntStream.range(1, 100)
.mapToObj(Task::new)
.collect(Collectors.toList());...
2024年05月27日
相比于synchronized内置锁隐式地加锁和释放锁的方式,ReentrantLock则采用显式地加锁和释放锁的方式,如下代码:
java
private final ReentrantLock lock = new ReentrantLock();
public void m() {
lock.lock();
try {
// ... method b...
2024年05月18日
当多个线程对同一个变量进行修改时,可能会产生以下线程安全问题:
CPU缓存导致的可见性问题。
指令重排序导致的有序性问题。
线程切换导致的原子性问题。
线程不安全的累加器
如下代码,UnsafeCount类是一个累加器:
java
public class UnsafeCount {
private int value = 0;
public void in...
2024年05月15日
当共享资源被多个线程同时访问时,可能会产生不符合预期的并发问题。为了保证共享资源在某一时刻只能被一个线程访问到,则需要对资源进行加锁,为此Java提供了一种易用的内置锁synchronized[^1]。锁的添加和释放过程如下:
在访问共享资源前,线程需要获取锁。如果获取锁成功,则访问共享资源;如果获取锁失败,则阻塞该线程,等待其他线程释放锁之后重新尝试获取锁。
在访问共享资源后,持有锁...
2024年04月22日
相比于JDBC的编程式事务,Spring提供了一种更便捷的处理事务的方式,即声明式事务。我们只需要在方法或类上标注@Transactional注解便可完成事务的声明,如下示例:
java
@Transactional(rollbackFor = Exception.class)
public void pay() {
jdbcTemplate.execute("update balanc...
2024年04月10日
得益于SpringBoot的封装,我们只需要简单的几行代码便可启动一个Spring应用,如下示例:
java
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplicatio...
2024年03月30日
什么是自动配置?
当我们需要集成某些功能时,只需要依赖Spring Boot或第三方提供的Starter即可,自动配置机制会将相关的配置注册到容器中,开箱即用,降低了开发人员的使用成本。通过@EnableAutoConfiguration注解可以开启自动配置。
以Spring Boot应用集成Redis为例,首先在pom文件中依赖springbootstarterdataredis,然后在...
2023年12月06日
什么是代码的可读性?
首先我们来看一段代码,并推测其实现了什么业务?
java
public double getA(double a, double b) {
return 3.14 * a * a * 2 + 2 * 3.14 * a * b;
}
然后我们再来看一段代码,并推测其实现了什么业务?
java
public double getSurfaceAreaOfCyli...
2023年11月16日
得益于Spring框架的封装,我们只需要简单的几行代码便可创建一个HTTP服务,如下代码:
java
@SpringBootApplication
@RestController
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(De...
2023年11月11日
Queue接口详解
Queue接口有哪些实现?
plantuml
interface Queue<E>
interface Deque<E>
class LinkedList<E>
class ArrayDeque<E>
class PriorityQueue<E>
Deque u|> Queue
LinkedList .u.|> Deque
ArrayDeque .u.|> Deq...
2023年10月24日
Set接口详解
Set接口有哪些实现?
plantuml
interface Set<E>
interface SortedSet<E>
interface NavigableSet<E>
class HashSet<E>
class LinkedHashSet<E>
class TreeSet<E>
abstract class EnumSet<E extends Enum<E>>...
2023年10月17日
Map接口详解
Map接口有哪些实现?
plantuml
interface Map<K,V>
interface SortedMap<K,V>
interface NavigableMap<K,V>
class HashMap<K,V>
class LinkedHashMap<K,V>
class TreeMap<K,V>
class EnumMap<K extends Enum<K...
2023年09月28日
List详解
List接口有哪些实现?
Java平台提供了两种常规用途的List接口的实现,分别是ArrayList和LinkedList。
在一般场景下,ArrayList有着更好的性能。
在特定场景下,LinkedList有着更好的性能。
plantuml
interface Iterable<E>
interface Collection<E>
interface Lis...
2023年09月25日
如何将一个Bean注册到IoC容器中?
如何将一个Bean注册到IoC容器中?
在Spring2.5之前的版本,可以通过XML配置的方式,也就是通过bean标签来配置Bean。
在Spring2.5及之后的版本,可以通过注解扫描的方式,也就是在类上标注@Component或其派生注解。
在Spring3.0及之后的版本,可以通过配置类的方式,也就是在类上标注@Configuratio...
2023年08月27日
BeanFactory和ApplicationContext有什么区别?
Bean工厂BeanFactory和应用上下文ApplicationContext两者都是IoC容器。
从功能上看,ApplicationContext是BeanFactory的超集,提供了环境,事件,资源,国际化,类型转换等一系列的企业级应用特性,这在接口的定义上也有体现。
从实现上看,Application...
2023年08月13日
在Bean的实例化之后,会进行Bean的初始化,也就是会调用Bean的初始化方法。有以下几种方式指定Bean的初始化方法:
1. 标注@PostConstruct注解到初始化方法上;
2. 实现InitializingBean接口的afterPropertiesSet方法;
3. 指定BeanDefinition的初始化方法。
在Bean的销毁之前,会调用Bean的销毁方法。有以下几种方式...
2023年08月05日
什么是依赖注入?
宽泛地讲,依赖注入(Dependency Inject,DI)是控制反转(Inversion of Control,IoC)的一种实现方式,本质上就是将依赖的创建和管理委派给IoC容器,使用者只需要声明要注入的依赖便可完成依赖的获取。在日常开发中,最常使用的Spring注解是@Component和@Autowired(或@Resource),前者将Bean注册到Sprin...
2023年07月25日
以XML配置文件配置的Bean为例,搞明白Bean在Spring中是如何被加载的可以使我们更了解Spring的XML配置文件中有哪些配置信息,以及各个配置信息是如何生效的。Spring的XML配置文件提供了很多标签和属性,我们不仅可以使用bean标签配置Bean,使用alias标签配置别名,还可以使用import标签导入资源,使用componentscan标签开启组件扫描等。
> 根据二八...
2023年07月05日
为什么要搞清楚Bean在Spring中是如何表示的,主要有以下两个方面的原因:
1. 对于使用者来说,在使用XML或注解配置Bean时,需要知道有哪些配置项,才能进行配置;
2. 对于开发者来说,在Spring处理Bean的过程中,会依赖Bean在Spring中的表示,是阅读源码的前置知识。
如果让你设计,你会如何设计?
我们使用Spring是为了让Spring帮我们创建和管理依赖(...
2023年07月05日