想要解决问题首先要明确问题并正确的剖析问题。
首先明确:在什么情况下会出现线程安全问题?
答:在多个线程同时对一个全局变量或一个静态变量进行写操作时,会发生线程安全问题。而读操作是不会发生线程安全问题的。
那么怎么才解决多线程的安全问题。
1.使用synchronized 关键词。
synchronized 可以保证同一时刻只有一个线程访问某一方法或某个代码块,同时synchronized可以实现某个线程变化可见。(即:可见性) 可以代替 volatile。
可见性的实现原理:
每个线程都一个私有的本地内存,私有内存的数据是主内存数据的复制,所以说线程与线程之间是不可见的,要借助于synchronized或volatile,使得线程之间可见,(volatile 只能保证线程之间可见,不保证线程安全)
2.使用synchronized的三种方法:
(1)同步代码块
就是把有可能造成线程安全问题的代码包括起来;
synchronized(同一个数据){
可能会发生线程冲突问题
}
(2)同步函数
就是使用synchronized 修饰 某一方法。
(3)静态同步函数
用static修饰synchronized修饰的方法或使用当前类.class 文件
静态的同步函数使用的锁是 该函数所属字节码文件对象
可以用 getClass方法获取,也可以用当前 类名.class 表示。
例子:
synchronized (ThreadTrain.class) {
System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
trainCount--;
try {
Thread.sleep(100);
} catch (Exception e) {
}
}
3.总结
同步函数使用的是的this锁
静态同步函数使用锁是当前字节码文件。
线程安全就必须保证 :共享变量线程间的可见性、临界区代码访问的顺序性。
一章讲解synchronized 和volatile的区别~~~~~~~~~~~~