线程安全的小例子

class ThreadTest extends Thread{

    static int ticketNum = 50; //一定要设置为静态变量,这样多个对象实例共享的是一份数据,操作的也是同一份数据
    
    public ThreadTest(String name) {
        // TODO Auto-generated constructor stub
        super(name);
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        while(true){
                if(ticketNum>0){
                    System.out.println(this.getName()+"售出了第"+(50-ticketNum+1)+"张票");
                    ticketNum --;
                }else{
                    System.out.println("卖完了.....");
                    break;
                }
        }
        }
            
}
	//main方法
	public static void main(String[] args) {
		ThreadTest t1 = new ThreadTest("窗口1");
		ThreadTest t2 = new ThreadTest("窗口2");
		ThreadTest t3 = new ThreadTest("窗口3");
		t1.start();
		t2.start();
		t3.start();
	}

  

我们看看结果
窗口2售出了第1张票
窗口1售出了第1张票
窗口1售出了第3张票
窗口3售出了第1张票
窗口1售出了第4张票
窗口2售出了第2张票
窗口1售出了第6张票
窗口3售出了第5张票
窗口1售出了第8张票
窗口2售出了第7张票
窗口1售出了第10张票
窗口3售出了第9张票
窗口1售出了第12张票
窗口2售出了第11张票
窗口1售出了第14张票
窗口3售出了第13张票
窗口1售出了第16张票
窗口2售出了第15张票
窗口1售出了第18张票
窗口3售出了第17张票
窗口1售出了第20张票
窗口2售出了第19张票
窗口1售出了第22张票
窗口3售出了第21张票
窗口1售出了第24张票
窗口2售出了第23张票
窗口1售出了第26张票
窗口3售出了第25张票
窗口1售出了第28张票
窗口2售出了第27张票
窗口1售出了第30张票
窗口3售出了第29张票
窗口1售出了第32张票
窗口2售出了第31张票
窗口1售出了第34张票
窗口3售了第33张票
窗口1售出了第36张票
窗口2售出了第35张票
窗口1售出了第38张票
窗口3售出了第37张票
窗口1售出了第40张票
窗口2售出了第39张票
窗口1售出了第42张票
窗口3售出了第41张票
窗口1售出了第44张票
窗口2售出了第43张票
窗口1售出了第46张票
窗口3售出了第45张票
窗口1售出了第48张票
窗口2售出了第47张票
窗口1售出了第50张票
卖完了.....
窗口3售出了第49张票
卖完了.....
卖完了....

//结果中我们可以看到有的同一张票被卖出了两次,这就是不同的线程在访问共享数据时容易出现的问题,由于上一线程的操作未结束,下一线程又进行操作,就造成数据更新不及时,也就出现了线程的安全问题。
原文地址:https://www.cnblogs.com/it-life-nathan/p/6888660.html