您现在的位置:首页 > 教案格式 > 正文

变量之间的相关关系 (转载)有关线程安全的探讨--final、static、单例、线程安全

2017-12-22 17:04 网络整理 教案网

变量之间的因果关系_变量之间的相关关系_相关关系是指变量之间

变量之间的相关关系变量之间的相关关系

什么样的代码是天生线程安全的?而不用加锁

线程是否安全的本质是什么?

什么是快速把一段代码变成线程安全的通用方法

final static 单例 线程安全 之间的关系

1、首先我们知道,如果线程只是执行自己内部的代码(其实也是使用一些对象的方法,但是是局部变量,那么就线程安全),那一定是线程安全的

这句话严格一些说可以是这样:线程使用在run( )方法中实例化的局部变量的方法,是线程安全的

2、那下一个问题就是,一个线程能调用哪些代码,或者说能访问到哪些东西?访问这些东西的安全性如何?

继承并重写一个Thread类,然后在使用的时候实例化这个类,最后调用这个对象实例的start方法启动

这种方式的run方法中,其实能调用的东西就很少了

你在继承时加的成员变量。(完全不会有线程是否安全的问题,因为这个类就一个run()方法是多线程方法,就跟在run()中实例化的局部变量一样)

通过构造方法从外面传入的变量。(这种方式需要警惕!因为传递的是引用,如果你在线程中对这个引用指向的内容进行修改,那么会影响到原来的东西!)

使用其他的代码段(方法)

静态方法(类似单例模式)

实例方法——通过实例对象

使用其他的对象

静态对象

实例对象

(两面两大点中,使用实例方法和实例对象都是线程安全的。而使用静态方法和静态对象时,是一定会冲突的)

所以总结一下,这种方式中

线程安全的有

在继承时加的成员变量

实例化其他对象,使用这个对象,或者使用这个对象的方法

不安全的有

变量之间的相关关系_变量之间的因果关系_相关关系是指变量之间

通过构造方法从外面传入的变量

静态方法

静态对象

使用匿名内部类

这种方式,在上一种方式的继承上,只少了构造方法的方式,然后多了好几种危险的方式, 需要注意

所处方法中的局部变量

这个值得一提,本来这项是肯定会线程不安全,而且非常常用,所以危险指数五颗星的,但是JAVA特地为此限定了一条规则,就是这样的局部变量必须是final的,不能修改,于是这个就变得非常安全了

但这条其实可以通过引用类型绕过,就是另一回事了,其实也说明了它的不安全

所处类中的属性

所处类中的方法

方法本身不会有问题,问题的根源是(普通方法、静态方法)方法使用了变量(相对全局变量,或者说叫可共享变量)【比如静态成员、类属性等等】

匿名类中更加危险,要谨慎调用

不能同时被多个线程调用

这个是最普通的,也是常规上我们的线程安全的含义

这个问题可以通过加锁解决

不能被多个线程调用(不同时也不行)

这个在第一类的程度上有所增加,不是常用的情况,可能你不仅是要使用变量,你还需要记录变量的值

这个问题一般是把相关变量变成ThreadLocal的

不能被超过一次地调用

这个的情况更加特殊

一般使用单例模式解决

final

意思是,这个对象的值(基本类型就是值,引用类型是引用地址),不会再被改变

相关关系是指变量之间_变量之间的相关关系_变量之间的因果关系

与线程安全的关系,如上文,一定程度上能使某些变量强制变得线程安全

static

意思是,这个对象是一个全局变量了,你可以在多个地方,多个线程中调用到它,而且调用的是同一个它

与线程安全的关系,一般这种的变量很容易造成线程不安全的情况

单例

这首先是一种特殊的需求,就是某个类的实例在JVM中只能存在一个,跟前面的static,线程安全都不一样

与线程安全的关系。实现单例需要考虑复杂的多线程的情况,这个东西需要线程安全

因为创建一个 SimpleDateFormat实例的开销比较昂贵,解析字符串时间时频繁创建生命周期短暂的实例导致性能低下

在程序中我们应当尽量少的创建SimpleDateFormat 实例,因为创建这么一个实例需要耗费很大的代价。在一个读取数据库数据导出到excel文件的例子当中,每次处理一个时间信息的时候,就需要创建一个SimpleDateFormat实例对象,然后再丢弃这个对象。大量的对象就这样被创建出来,占用大量的内存和 jvm空间。