线程安全问题产生的原因
1、多个线程在操作共享数据
2、操作共享数据的代码有多条
当一个线程在执行操作共享数据的多条代码过程中,其它线程参与了运算,就导致线程安全问题的产生。
解决:将多条操作共享数据的线程代码封装起来,当有线程执行这些代码的时候,其它线程不可参与运算,必须当前线程把这些代码执行完毕后,其它线程才可参与运算。
synchronized 同步关键字
java中同步代码块可解决此问题
格式:
synchronized(对象)
{
需被执行的代码块
}
同步的好处:解决线程安全问题
同步的弊端: 相对降低了效率,同步外的线程都会判断同步锁。
同步的前提:必须多个线程使用同一个锁
同步函数使用的锁是 this
同步函数与同步代码块的区别:同步函数锁是固定的 this 静态同步函数使用的锁是该函数所属字节码文件对象,可用getClass方法获取也可用当前 类名.class表示
同步代码块的锁是任意的对象。
建议使用同步代码块。
同步死锁
同步死锁:常见的体现形式之一:同步的嵌套。
死锁示例:
class DeadLock implements Runnable {
private boolean flag;
DeadLock(boolean flag) {
this.flag = flag;
}
public void run() {
if (flag) {
synchronized (MyLock.mylocka) {
System.out.println(Thread.currentThread().getName() + "...if....locka.");
synchronized (MyLock.mylockb) {
System.out.println(Thread.currentThread().getName() + "...if....lockb.");
}
}
} else {
synchronized (MyLock.mylockb) {
System.out.println(Thread.currentThread().getName() + "...if....lockb.");
synchronized (MyLock.mylocka) {
System.out.println(Thread.currentThread().getName() + "...if....locka.");
}
}
}
}
}
class MyLock {
public static final Object mylocka = new Object();
public static final Object mylockb = new Object();
}
public class DeadLockTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
DeadLock d1 = new DeadLock(true);
DeadLock d2 = new DeadLock(false);
Thread t1 = new Thread(d1);
Thread t2 = new Thread(d2);
t1.start();
t2.start();
}
}