首页 / JAVA  

多线程下的线程安全问题的产生


定义:线程安全是多线程编程下,多条线程并行执行对共享数据进行操作时,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。

问题分析:

既然是线程安全问题,那么毫无疑问所有的隐患都是出现在多个线程访问的情况下产生的,也就是我们要确保在多条线程访问的时候,我们的程序还能按照我们预期的行为去执行,我们看一下下面的代码。
public class MyThread implements  Runnable{
public static int count = 20; // 票数
public Object objLock = new Object() ;
@Override
public void run() {
while(count>0) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
sale();
}
}

public void sale(){

System.out.println(Thread.currentThread().getName()+"-卖出第:"+(20 - count +1));
count--;
}
public static void main(String[] args) {
MyThread thread = new MyThread();
Thread mThread1 = new Thread(thread,"售票窗口01");
Thread mThread2 = new Thread(thread,"售票窗口02");
Thread mThread3 = new Thread(thread,"售票窗口03");
mThread1.start();
mThread2.start();
mThread3.start();
}
}
售票窗口02-卖出第:1
售票窗口01-卖出第:1
售票窗口03-卖出第:1
售票窗口01-卖出第:4
售票窗口03-卖出第:5
售票窗口02-卖出第:6
售票窗口01-卖出第:7

由运行结果可以看出三个售票口同时卖出了第一张票,这从逻辑上是有问题的
这是由于程序并发带来的问题,在售卖第一张票时两个线程同时进入了售票的方法,

当第一个进来的线程还没来得及进行 count-- 操作,其它的线程已经执行了

System.out.println(Thread.currentThread().getName()+"-卖出第:"+(20 - count +1));

所以出现了上面的情况

总结:在多线程编程中,这种存在竞争的线程就会出现线程安全问题
2019-10-22