Java学习日记——DAY21
先获取锁对象之后复制其引用,现在栈里有两个锁元素,将一个存储到slot1中,另一个的markword置为Monitor,完成操作后将slot1中的锁对象导出,将栈顶的锁对象markword重置还原,并唤醒entryList。Monitor的Owner是指锁目前的拥有者,在程序开始时为null,EntryList中的元素是正在等待获取锁的线程,WaitSet中的元素是进行线程休眠的线程(wait);
我今天针对多线程的知识继续展开了学习,学习内容如下:
1.当一段代码块实现了对共享资源的多线程读写,则这段代码块称为临界区,如两个线程同时对共享的int对象分别进行加减处理;
2.当一个对象或一个不同步的共享状态被两个或两个以上线程同时修改时,对访问的顺序必须严格执行,否则会形成静态条件;
3.为了解决临界区问题,使用syschronized机制:
(1)syschronized(对象):指定对象作为锁;
(2)syschronized作为修饰词修饰方法:锁方法,如果是实例方法则等价于syschronized(this),如果是静态方法则等价于syschronized(this.class);
针对syschronized字节码的分析:
先获取锁对象之后复制其引用,现在栈里有两个锁元素,将一个存储到slot1中,另一个的markword置为Monitor,完成操作后将slot1中的锁对象导出,将栈顶的锁对象markword重置还原,并唤醒entryList
Code:
0: getstatic #2 // Field obj:Ljava/lang/Object;
3: dup //将上面对象复制
4: astore_1 //将obj对象引用存储到临时变量中 slot 1中
5: monitorenter //将obj对象Markword设置为Monitor指令
6: getstatic #3 // Field x:I
9: iconst_1
10: iadd
11: putstatic #3 // Field x:I
14: aload_1 //从slot 1中 加载obj对象,找到对应的monitor对象
15: monitorexit //将obj对象Markword重置还原,唤醒EntryList
16: goto 24 //如果正常情况,代码执行到24标识,结束
19: astore_2 //异常情况 将异常对象e 存入slot 2
20: aload_1 //同14
21: monitorexit //同15
22: aload_2 //将异常对象从slot2加载出来
23: athrow //抛出异常
24: return
Exception table:
4: invokespecial #1 // Method java/lang/Object."
<init>":()V
7: putstatic #2 // Field obj:Ljava/lang/Object;
10: iconst_0
11: putstatic #3 // Field x:I
14: return
}
下面是Monitor机制

syschronized(obj){
while(条件){
obj.wait();
}
}
进行操做
6.死锁
如果一个线程使用了多把锁,则容易产生死锁现象;
死锁产生的条件:
(1)互斥条件:每个锁都只能同时被一个线程占有;
(2)请求和保持条件:一个线程在请求资源的同时占有资源;
(3)不剥夺条件:当前线程已获得的资源,在没有使用完之前,不能强行剥夺;
(4)循环等待条件:若干个线程之间形成一种头尾相连的循环等待资源关系;
死锁的处理:
(1)预防死锁:破坏死锁的四个条件之一,不能破坏互斥条件;
(2)避免死锁:在资源动态分配过程中,使用某种方式阻止系统进入不安全状态;
(3)检测死锁:允许系统在运行过程中产生死锁,并检验出来进行处理清除;
(4)解除死锁,采用资源剥夺法,撤销进程法,进程回退法等,将进程从死锁状态解脱出来。
7.volatile
修饰变量使线程在访问时会根据内存中的状态进行实时变化,即当一个线程修改了该变量的值,其他线程能立即看到最新值;
8.ThreadLocal
线程变量,该变量仅属于当先线程,该变量相对于其他线程来说是隔离的,ThreadLocal在每个线程里都创建一个副本,这样每个线程都可以访问自己内部的副本变量减少同一个线程内多个函数或组件之间一些公共变量来回传递的复杂度;
注意:
每个ThreadLocal都有自己的实例副本并且这个副本只能由当前的Thread使用;
不存在多线程间数据共享的临界区问题;
通常被static final修饰,当一个线程快结束时,它所使用的所有ThreadLocal副本都被回收;
9.ThreadLocal和syschronized的区别:
ThreadLocal偏重于实现线程间数据的隔离,而syschronized偏向于线程间的数据共享;
syschronized是利用锁的机制,使其包裹的代码块在某一时间段只能由一个线程访问。ThreadLocal为每一个线程都提供了变量的副本,使某个线程在某个时间点访问到的并不是同一个对象,实现了数据的隔离共享;
10.线程安全的类:
更多推荐



所有评论(0)