线程安全理解

一.线程安全示意图

 

 其中锁1,锁2表示该对象对应的类中某些具有锁功能的代码块,方法等。

如果锁1,锁2都是传统锁(synchronized)的话,

线程1.线程2,线程3,线程4,线程5之间都是互斥的,任何一个线程在执行,其他的线程都在等待。

 

 

二.线程安全的检测

在程序中,当一个类在没有做锁处理的情况,它的实例被多个线程共享时,就会可能存在线程安全问题。

分析的一般步骤的思路(也有其他特殊情况),作为参考:

第一步:在类的构造方法加上打印日志语句

第二步:在类的方法都加上 System.out.println(Thread.currentThread().getName());

第三步:  启动主线程,或者其他操作触发多线程(如web项目,我们一个请求就是触发一个线程)

第四步:  分析类的构造方法上日志是否打印一遍,而类的方法上日志打印多遍,且线程名称存在不同。这就是说明多个线程对同一个对象进行操作。

第五步:考虑线程安全,是否需要对这些方法(或者方法里的代码块)进行加锁处理。哪里加锁,加什么样的锁,锁的粒度等等,这样就需要根据具体

              情况具体分析,然后结合多线程的知识,测试的情况进行完善。

如果是多个线程共同调用同一个静态方法,那么如果考虑到线程安全就要用该类的字节码(****.class)作为锁来使用。

 所以要想让一个进程的线程产生共享,不管他们在什么地方,要让他们共享对象,或者共享类的静态属性和方法。

要想使之安全,互斥,就得加锁处理。

 

方法区,Java堆是对所有线程共享的,只是有的时候在某个线程中想要获取对象的实例,找不到引用的句柄,所以要想共享,就把该对象的引用传递到另一个线程里使用。

 

java虚拟机栈的理解:每一个线程的栈帧都是独立私有的,都有各自独立的栈帧机构(局部变量表,操作数栈,动态连接方法,返回地址),只有他们访问同一个对象,

类的static元素时才会需要做互斥处理。

 

java 对象锁可以是任何对象锁。

 

posted on 2020-06-01 14:44  芝麻开花——节节高  阅读(159)  评论(0编辑  收藏  举报

导航