一个进程里面 空间是共享的
多个线程 共享 进程的数据域,共享进程的堆区
如果 多个线程 操作一个进程会导致一个什么问题
数据不同步? 数据出错了 ?
以上不管怎样执行,每次执行输出的打印都不一样。
那这个时候,数据不同步了
这个时候 咋搞?
回答: 加锁
就是 synchronized
why?加了锁 为啥还是 没有同步?
回答:因为主线程的原因,fork出来的其他线程,只有等其他线程执行完毕了,主线程才会结束。
那么,如何解决?
回答:让主线程睡一会
这个时候,就达到我们想要的效果了,这就是加锁,同步了
主线程 会等待 它的 附属守护线程 执行完毕后
主线程 才会退出~(这就是为啥要睡一秒的原因)
守护线程 优先级是最低的
JVM在启动的时候开启两个线程
1 垃圾回收
2 主线程
那么接下来,谈谈volatile
这个时候,发现,
1 加了 volatile 关键字
2 去掉了 synchronized关键字
3 加了 join()
出现的效果,跟加锁一样的效果。
实际上,这样做的效果 就是 多线程的并发
多线程 多线程 从字面上看 ,就是多个线程的同时执行
上面是没有锁的并发执行着,但是呢?加上了 join().其实就是插队了,耍无赖。并且并发的线程这个时候,还要等这个插队的无赖先执行完,才能执行,所以也就看到了这样的加锁的一样的效果
but,再来看看一个奇怪的东东
发现 去掉了 volatile后,还是可以保证同步
其实,这就考查到了 volatile究竟是干嘛的了
volatile 只是可见性,不能保证原子性
单独用 么有什么用,也就只能保证一个 可见性而已
要与 CAS一起用
每个线程跑 不依赖上个线程的状态
Next,再来研究谈谈
这个时候,发现
1 不要 volatile
2 添加synchronized
3 去除join()
这个时候,心里估计又是在嘀咕了,怎么又不能同步了呢?
其实 这是由于 跟上文提到一样,主线程还没执行完
1 ACC_SYNCHRONIZED 线程标识
2 invokedynamic 线程独有
线程同步,想到的都是 synchronized加锁,那么他的原理是啥?
如果是 synchronized加在静态方法上
在字节码是无法看到它锁了,事实上是锁了整个类,也就是Class
so,在这里 就来谈谈一般实例方法
public class ThreadSynTest extends Thread {
public int count;
public void addLock() {
count += 1;
}
@Override
public void run() {
//给当前对象加锁
synchronized (this) {
addLock();
}
}
public static void main(String[] args) {
new ThreadSynTest().start();
}
}
看看底层 原理是啥
在执行run() 方法的时候
首先 aload_0 其实就是 this
然后 monitorenter
当monitorenter 进来后,就锁住了,其他对象就进不来了
然后这里又会涉及对象的概念
对象头 (锁标志位 持有该对象的线程数)
数据区
对齐填充
偏向锁 当线程第一次来了后
做一个标记,当下次还是这个对象进来的时候,就不上锁了
but why ? monitorexit 会出现两次
看看字节码,在这里,这字节码也不复杂,自己来解读一下吧!
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_0
5: invokevirtual #3 // Method addLock:()V
8: aload_1
9: monitorexit
10: goto 18
13: astore_2
14: aload_1
15: monitorexit
16: aload_2
17: athrow
18: return
这里 先回顾下 栈的知识
栈:栈帧 (局部变量表、操作数栈、指向常量池的索引、返回地址、、、)
0 :将0 槽位 也就是 this 也就是当前对象
推送至栈顶
1: 进行复制,入栈
2: 将栈顶存入局部有变量表
3: 对象监视锁
4: 将局部变量推送至栈顶
5: 实例化addLock()方法
8:将局部变量推送至栈顶
9: 对象监视锁释放
10:跳转到18 return 退出
13:将栈顶存入局部有变量表
14:将局部变量推送至栈顶
15: 对象监视锁释放
16: 将局部变量推送至栈顶
17:抛出异常
18:return 退出
从以上,可以看到,monitorexit 出现了两次,why?
这就是为啥 出现了两次的原因,抛出 了异常,锁要进行释放
1 一个是正常退出
2 另一个是 出现异常后释放锁,防止死锁
好了,这两篇也就算是自己谈谈Synchronized
若有理解,想法不对的地方,敬请批评指出
赶快来分享关注吖