概述
当多个线程共同访问一块内存时,便可能产生锁。考虑以下情况

线程A和线程B同时访问堆中的一个对象object,它们同时访问object.count变量,如果只是读取,不会存在如何问题,如果线程A和线程B都堆count进行改变。线程A发现如果count=0,该把count变成1,线程B发现如果count=0,就把A变成2。假设他们同时访问到count变量时,count=0,这是A先把count变成1,线程B接着把count变成2。线程A在进行访问时便出现了不一致的情况。
为了解决不一致的情况,必须堆变量A进行加速处理,同一时间段,只允许一个线程对线程A进行访问,JAVA采用对对象进行加锁的方式进行处理,每一个对象的头部都有markword字段,使用markword的几个bit位表明对象是否具有访问一块代码片段的权限。
验证:
验证环境:jdk1.8,VM参数:-XX:BiasedLockingStartupDelay=0
代码
import java.util.concurrent.TimeUnit;
import org.openjdk.jol.info.ClassLayout;
public class TestLock {
static class LockObject {
int i=0;
}
static class MyThread implements Runnable {
LockObject lock;
public MyThread(LockObject lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(3));
} catch (Exception e) {
}
}
}
}
public static void main(String[] args){
LockObject lock = new LockObject();
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
new Thread(new MyThread(lock)).start();
// new Thread(new MyThread(lock)).start();
}
}运行结果:
TestLock$LockObject object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 43 c0 00 f8 (01000011 11000000 00000000 11111000) (-134168509)
12 4 int LockObject.i 0
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
TestLock$LockObject object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 40 c3 1b (00000101 01000000 11000011 00011011) (465780741)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 43 c0 00 f8 (01000011 11000000 00000000 11111000) (-134168509)
12 4 int LockObject.i 0
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total只有一个线程访问代码块时默认开启的是偏向锁:101
当开启两个线程时,锁变成了 010 (重量级锁),结果如下
TestLock$LockObject object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 43 c0 00 f8 (01000011 11000000 00000000 11111000) (-134168509)
12 4 int LockObject.i 0
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
TestLock$LockObject object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 6a 40 72 02 (01101010 01000000 01110010 00000010) (41042026)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 43 c0 00 f8 (01000011 11000000 00000000 11111000) (-134168509)
12 4 int LockObject.i 0
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
TestLock$LockObject object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 6a 40 72 02 (01101010 01000000 01110010 00000010) (41042026)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 43 c0 00 f8 (01000011 11000000 00000000 11111000) (-134168509)
12 4 int LockObject.i 0
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total锁的处理思路:
java中:对象头中
数据库:页锁