java中什么是线程安全给出一个例子
什么是线程安全? 马克-to-win: 最大的大白话,你的代码一个线程执行挺好,一上多线程测试就玩儿完(结果不是你所想要的),这就是线程不安全。反之为线程安全。首先,我们把第二章讲单态模式或单例模式(Singleton)的例子再搬过来一次,但这里把一些无关的打印和注释去掉了:
马克- to-win:马克 java社区:防盗版实名手机尾号: 73203。
例:1.8.1-本章源码
class Photoshop {
private Photoshop() {
}
private static Photoshop photoshop = null;// 这个值独立于任何对象存在,实例化任何对象之前,这个成员就有可能有值。
public static Photoshop getInstanceQixy() {
if (photoshop == null) {
photoshop = new Photoshop();
}
return photoshop;
}
}
public class Test {
public static void main(String[] args) {
Photoshop photoshopI1 = Photoshop.getInstanceQixy();
Photoshop photoshopI2 = Photoshop.getInstanceQixy();
System.out.println(photoshopI1+" "+photoshopI2);
}
}
输出结果:
Photoshop@1b67f74 Photoshop@1b67f74
后序:上面的例子一切都正常,就是一个非常普通的单态模式的实现。但要想上面的例子正确运行,我们必须确保运行环境是单线程的。如果运行环境是多线程的,以上的单态模式的实现,就有一定的机率,运行得不到正确的结果了。以下我用实验(下面的例子)来说明我这一论点。
例:1.8.1_b-本章源码
class Photoshop {
private Photoshop() {
}
private static Photoshop photoshop = null;
public static Photoshop getInstanceQixy() {
if (photoshop == null) {
photoshop = new Photoshop();
}
return photoshop;
}
}
class MyThreadMark_to_win extends Thread {
public void run() {
Photoshop photoshopI1 = Photoshop.getInstanceQixy();
System.out.println(Thread.currentThread().getName() + "实例是 "
+ photoshopI1);
}
}
public class Test {
public static void main(String[] args) {
MyThreadMark_to_win mt1 = new MyThreadMark_to_win();
MyThreadMark_to_win mt2 = new MyThreadMark_to_win();
mt1.start();
mt2.start();
}
}
输出结果有时是(占少数):
Thread-1实例是 Photoshop@1270b73
Thread-0实例是 Photoshop@89ae9e
而输出结果多数是:(占多数)
Thread-0实例是 Photoshop@a62fc3
Thread-1实例是 Photoshop@a62fc3
后序:因为两个线程同时启动,如果一个线程执行完photoshop = new Photoshop();以后,另外一个线程执行if (photoshop == null)判断,则只会得到一个photoshop实例。然而对于得到了两个photoshop实例结果的这种情况,一定是这两个线程同时执行if (photoshop == null)这句指令造成的。而线程的执行顺序和速度是我们人为不可控的。这就是程序得到以上两种结果的原因。既然你的目的是编一个单例的程序,单线程时结果正确,而在多线程执行环境时,结果得到了两个实例,(结果非预期),这种情况就说,我们编的代码Photoshop类是线程不安全的。马克-to- win:如果你确定你的代码不会在多线程的环境下执行,线程不安全的代码也没关系,因为通常情况下解决线程不安全要用synchronized,会影响性能。如果你确定你的代码不会。。。。。更多内容,进入: