一、什么是线程不安全?
大家先看下面一段代码有什么问题?
static int count = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
count++;
}
}, "t1");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
count--;
}
}, "t2");
t1.start();
t2.start();
t1.join();
t2.join();
log.debug("结果为:{}",count);
}
输出结果:
17:26:54.697 [main] - 结果为:667
此处开启了两个线程对count进行++和--操作,按理来说最后执行结束程序的结果应该为0,但是却得到了异常的结果。
- 我们可以看出,上述代码中的count为共享变量,被多个线程所共享,而++和--操作指令并不是原子性的,在线程发生上下文切换的时候,会导致指令执行的顺序不一致,从而导致最终执行的结果发生了异常,这就发生了线程不安全的现象。
- 线程安全问题大多是由全局变量及静态变量引起的,局部变量逃逸也可能导致线程安全问题。
二、如何解决线程不安全的问题?
1.synchrozied
static int count = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
synchronized (Test1.class){
count ++;
}
}
}, "t1");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
synchronized(Test1.class){
count --;
}
}
}, "t2");
t1.start();
t2.start();
t1.join();
t2.join();
log.debug("结果为:{}",count);
}
输出结果:
17:51:47.795 [main] - 结果为:0