1.线程安全问题产生的原因
在使用多线程解决问题的时候,因为多个线程对同一共享数据的操作破坏了数据的原子性,而导致产生了线程安全问题。(原子性:从字面意思来看是指不可分割的,那么原子性则是,当一个线程对一个多个线程共享的数据进行操作时,是不可分割的。通俗来讲是指,当一个线程对共享数据操作时,其他线程不能对该共享数据进行操作)
举个例子:两个人共同使用一张银行卡,这个银行卡里有1000元存款,两个人在不同的atm机都登录了账户,都要取出1000元,此时,对于每一个人来说,账户都有1000元,他们都可以取出。这时则发生了线程安全问题。
2.火车站卖票问题
题目:火车站有三个卖票的窗口,共卖100张火车票。每张票都有唯一的票号
很显然这道题需要使用三个线程来模拟卖票的窗口,这三个线程需要共同操作一个唯一的变量ticket.
首先实现代码如下:
继承Thread类的方式:
class Window extends Thread{
private static int ticket = 100;
@Override
public void run() {
while (true){
try {
sleep(100); //加大出现重票错票的概率
} catch (InterruptedException e) {
e.printStackTrace();
}
if(ticket > 0){
System.out.println(Thread.currentThread().getName() + ": 卖票,票号为: " + ticket);
ticket --;
}else {
break;
}
}
}
}
public class WindowTest {
public static void main(String[] args) {
Window w1 = new Window();
Window w2 = new Window();
Window w3 = new Window();
w1.setName("窗口1");
w2.setName("窗口2");
w3.setName("窗口3");
w1.start();
w2.start();
w3.start();
}
}
实现runnable接口的方法:
class Window1 implements Runnable{
private int ticket = 100;
@Override
public void run() {
while (true){
if(ticket > 0){
System.out.