先来看一个实现卖票的程序:
public class TicketSell {
public static class RunnableIimpl implements Runnable {
//定义一个多个线程共享的票源
private int ticket = 100;
//设置线程任务:卖票
@Override
public void run() {
//使用死循环让买票重复循环
while (true) {
//判断票是否存在
if (ticket > 0) {
//存在:卖票
try{
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "--->正在卖第" + ticket + "张票");
ticket--;
}
}
}
}
public static void main(String[] args) {
//创建Runnable接口的实现类对象
RunnableIimpl runnableIimpl = new RunnableIimpl();
//创建Thread类对象,构造方法中传递Runnable接口的实现类对象
Thread t0=new Thread(runnableIimpl);
Thread t1=new Thread(runnableIimpl);
Thread t2=new Thread(runnableIimpl);
//调用start方法,开启多线程
t0.start();
t1.start();
t2.start();
}
}
结果出现了重复卖票和卖不存在票的情况:
这里Thread-2和Thread-0都在执行卖第99张票,原因是因为t0,t1,t2同时执行到了 “正在卖第”+ticket+“张票”
这时候ticket还没有执行到–
对于出现 不存在的票的情况,具体原因可以参照下图分析 :
所以需要注意:
线程安全问题是不能产生的,我们可以让一个线程在访问共享数据的时候,无论是否失去了cpu的执行权,让其他的线程只能等待,等待当当前线程卖完票,其他的线程再进行卖票,保证使用一个线程在卖票。