线程安全问题产生的原因:
1,多个线程在操作共享的数据;
2,操作共享数据的线程代码有多条;
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
解决思路:
就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程是不可以参与运算的。
必需要当前线程把这些带那都执行完毕后,其他线程才能参与运算。
在java中用同步代码块就可以解决这个问题
同步代码块的格式:
synchronized(对象){
需要被同步的代码;
}
同步的好处:解决了线程的安全问题。
同步的弊端:相对降低了效率,因为同步外的线程都会判断同步锁。
同步的前提:同步中必须有多个线程并使用同一个锁。
同步有两种:
1,同步代码块:
class Bank{
private int sum;
public void add(int money){
synchronized(this){
sum += money;
System.out.println(Thread.currentThread().getName()+"********"+"sum = "+sum);
}
}
}
2,同步函数:
e.g.
class Bank{
private int sum;
public synchronized void add(int money){
//synchronized(this){
sum += money;
System.out.println(Thread.currentThread().getName()+"********"+"sum = "+sum);
//}
}
}
同步函数所使用的锁是this;
同步函数和同步代码块的区别:
同步函数的锁是固定的this;
同步代码块的锁是任意的对象。
建议使用同步代码块。
静态的同步函数使用的锁是该函数所属字节码文件对象
可以用getClass()方法来获取,也可以用当前 类名.class表示