多线程的安全问题表现:
先看如下代码:
package chapter1502;
public class Ticket1 implements Runnable{
private int tickets = 100;
public void run(){
while(true){
if(tickets>0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + tickets--);
}
}
}
}
(此处为简单起见,省略了main() 函数)
运行这段代码会发现,出现着这种状况:
很显然,在卖票的这个实际例子中这是不成立的,不可能出现负的情况。
那么为什么会发生这种状况呢?
出现这种状况的原因:
当tickets 剩余值为 1 时,线程0 来判断 tickets > 0 , 进入 if 中,但 进入之后 被sleep 了 10毫秒,
恰恰在这个时候,线程1 也来判断 tickets> 0 , 满足条件,进入 if 中,但在进入后 也背 sleep 了 10 毫秒,
线程2 , 3 ,也会进行同样的操作。当 线程 0 sleep 时间到了之后,就会tickets-- ,这时 tickets 的值就是 0 ,
而线程 1 , 2 , 3 睡醒之后 就会直接打印 tickets 的值于是就出现了 tickets 为负的情况,
这就是 在卖票的这个实例中,出现 多线程安全问题的呈现 形式及原因。
在本例中 有线程 0 , 1 , 2 , 3 在操作共享数据 100 张票,并且操作共享数据的代码有多条。
当其中的一个线程在执行多条操作共享数据的过程中其他线程也参与了运算,这时候 就发生了 安全问题。
由此可以得出多线程出现安全问题的原因:
a) 多个线程在操作共享数据
b) 操作共享数据的代码有多条
当一个线程在执行多条操作共享数据的过程中,其他线程参与了运算,这时就会发生安全问题。
故而,分析多线程安全的依据就是:
1,线程任务中有没有共享数据;
2,该数据是否被多条语句操作。