AbstractQueuedSynchronizer排他锁分析

ThreadPoolExecutor.Worker 继承自 AbstractQueuedSynchronizer,并实现了一些锁相关的方法:

1
2
3
4
public void lock()        { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }

锁的实现:

1
2
3
4
5
6
public final void acquire(int arg) {
// 利用CAS尝试去更新state,如果失败就要进入等待队列
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}

Read More ...

IDEA心得不定期更新

记录一些 IDEA 使用中的各种小问题

代码格式化

alt + command + L

debug step in 失效

红框内的打钩去掉就OK了,看源码的时候勾上了真是蛋疼

另外,如果 debug 的代码是一个非 Main 的线程,但是如果 debug 到一半 Main 方法结束,即 JVM 运行结束,会导致 step in 按下以后直接结束掉。这个时候像个办法让 Main 方法永远不结束就行了。

Read More ...

Java类加载探究

class loading 理解

编译型语言的连接和Java的连接

C/C++等纯编译语言从源码到最终执行一般要经历:编译、连接和运行三个阶段,连接是在编译期间完成,而java在编译期间仅仅是将源码编译为Java虚拟机可以识别的字节码Class类文件,Java虚拟机对中Class类文件的加载、连接都在运行时执行

http://www.cnblogs.com/hnlshzx/p/3533264.html

编译型语言有连接,Java 也有连接,那么所谓的连接到底是干什么的。C 的连接:

把外部函数的代码(通常是后缀名为.lib和.a的文件),添加到可执行文件中。这就叫做连接(linking)。这种通过拷贝,将外部函数库添加到可执行文件的方式,叫做静态连接(static linking),后文会提到还有动态连接

http://www.ruanyifeng.com/blog/2014/11/compiler.html

看起来就是所谓连接,连接的是将有相互调用关系的代码(函数)对接到一起,让他们组织成一个可执行的整体(他们有调用关系,本来就该在一起)。那么 Java 的连接有是啥(Linking)?

Read More ...

Spring IOC循环引用源码分析

Spring bean 有两种注入方式,构造器注入和 set 注入。后者经过测试循环引用是不会报异常的,前者会报异常。

set 的方式

set 的方式默认是支持循环引用的,如果想设置成不支持,可以将 BeanFactory 实现类的 allowCircularReferences 设置成 falses。ApplicationContext 和 BeanFactory 基础的实现类都有这个参数可以设置。

spring 初始化 bean 的时候,是先构造一个空的对象,然后再根据需要去初始化属性指向的 bean。比如 B1 -> B2 为 B1 后属性引用 B2,同时 B2 -> B1。当去初始化 B2 的时候,在设置自己指向 B1 的属性时,是直接用 B1 还未完全构造完成的对象。

比如 B2 在需要去设置对 B1 的引用时,会调用 BeanFactory 的 getBean 方法。这个 getBean 方法的逻辑在最前端会去查一个缓存,这个缓存里放了先前已经开始初始化,但是还没有把属性设置完全的 bean 引用缓存。如果缓存非空,就直接用这个引用返回。如果缓存为空,就去调一个 ObjectFactory 对象的 getObject 方法作为 bean 引用返回。这个 ObjectFactory 是先前 B1 初始化时,被 new 出来以后,加进一个 ObjectFactory 容器的:

1
2
3
4
5
6
// AbstractAutowireCapableBeanFactory.doCreateBean
addSingletonFactory(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});

Read More ...

MySQL一例间隙锁分析

研究间隙锁的时候碰到一个问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> select * from t2;
+----+------+
| id | a |
+----+------+
| 1 | 2 |
| 3 | 4 |
| 6 | 5 |
| 8 | 5 |
| 10 | 5 |
| 13 | 11 |
+----+------+

Read More ...

MySQL文档翻译:幻影行

The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.

所谓的幻影读问题是在同一个事务内两次执行一个相同的查询,最终查询到的结果不一致。举个例子,如果一个 select 执行两次,第二次的查询结果返回了一行第一次查询所没有返回的结果,就说这行数据是一行「幻影」。

Suppose that there is an index on the id column of the child table and that you want to read and lock all rows from the table having an identifier value larger than 100, with the intention of updating some column in the selected rows later:

1
2
> SELECT * FROM child WHERE id > 100 FOR UPDATE;
>

Read More ...

MySQL一例锁分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
show create table banner;
CREATE TABLE `banner` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '元素ID',
`name` varchar(20) NOT NULL COMMENT '元素名称',
`city` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8;

mysql> select * from banner;
+----+------+------+
| id | name | city |
+----+------+------+
| 3 | a | 2 |
| 33 | xx | 1 |
| 34 | xx | 1 |
| 35 | xx | 1 |
| 36 | a4 | 1 |
| 37 | a4 | 1 |
| 38 | a4 | 0 |
| 41 | a | 0 |
+----+------+------+

Read More ...

如何查看MySQL加锁状态

information_schema.innodb_locks

这个表罗列了两类锁:

  • 事务请求了但是还没有获取到的锁
  • 事务持有的锁,并且这个锁阻塞了其他事务的执行

The INNODB_LOCKS table contains information about each lock that an InnoDB transaction has requested but not yet acquired, and each lock that a transaction holds that is blocking another transaction.

Read More ...