1.起源于一个问题
场景一:线程安全吗?
static String lock1 = new String("aaa");
static String lock2 = new String("bbb");
public static void test3(){
synchronized (lock1) {
// 业务代码会被锁住吗?
lock1 = lock1 + "x";
i++;
}
}
public static void main(String[] args) throws Exception{
for(int i=0;i<10000;i++){
new Thread(new Runnable() {
@Override
public void run() {
test3();
}
}).start();
}
System.out.println("结果是:" + i);
}
结果是 i=10000
场景二:线程安全吗?
public static void test(){
synchronized (lock1) {
// 业务代码
j++;
}
}
public static void main(String[] args) throws Exception{
System.out.println("-----------一秒后替换-------------");
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock1 = lock2;
}
}).start();
for(int j=0;j<10000;j++){
new Thread(new Runnable() {
@Override
public void run() {
test();
}
}).start();
}
System.out.println("结果j是:" + j);
}
结果是:j=10000
2.ReentrantLock对比
// CAS修改的字段
protected final void setState(int newState) {
state = newState;
}
//使用
public static void test4(){
ReentrantLock lock = new ReentrantLock();
// 锁----ReentrantLock中的state
lock.lock();
//业务逻辑
lock.unlock();
}
3.Sync到底锁的是啥
对象的结构:
1.属性:Java对象的实例数据(不固定)
2.对象头(固定)----12byte----96bit
3.数据对齐
对象头由:Mark word(64bit)、Klass pointer(32bit-开启指针压缩)组成