public class Test00 {
public static void main(String[] args) {
       TicketRunnable tr=new TicketRunnable();
       new Thread(tr,"线程1").start();
       new Thread(tr,"线程2").start();
       }
}class TicketRunnable implements Runnable {
    private int i=10;
    public void run(){
         while(i>=1){
         System.out.println(Thread.currentThread().getName()+"卖第"+i--+"张票");
         }
    
    }
}为什么结果有两种:
第一种:
线程1卖第10张票
线程2卖第9张票
线程2卖第7张票
线程2卖第6张票
线程1卖第8张票
线程1卖第4张票
线程2卖第5张票
线程2卖第2张票
线程1卖第3张票
线程2卖第1张票第二种:
线程1卖第10张票
线程1卖第9张票
线程1卖第8张票
线程2卖第10张票
线程2卖第6张票
线程1卖第7张票
线程1卖第4张票
线程2卖第5张票
线程2卖第2张票
线程2卖第1张票
线程1卖第3张票而且第二种的结果一般是程序运行7到8次才会出现。原理是什么?这涉及到cpu的工作原理?

解决方案 »

  1.   

    i--; 不是一个原子操作且i是共享的. 所以你的代码不是线程安全的. 
    但是由于循环10次的操作用时极短, 线程启动也是需要时间的, 所以出现不重复数据次数较少.想要保证正常出票可以将 int i=10;改为AtomicInteger i = 10; 或者将int i=10;前面加上volatile关键字.
      

  2.   

    加个锁就好了的
    while (i > 1) {
    synchronized (this) {
    System.out.println(Thread.currentThread().getName() + "卖第"+ i-- + "张票");}
    }
      

  3.   

    由于没有加锁,线程的运行你可以认为是无序的,既你无法确定当前是哪个线程在运行。这跟你的cpu有关系,是cpu控制的线程的运行
      

  4.   

    线程是cpu分配的,你没有加锁,这里就会有一个资源竞争问题。
      

  5.   

    你如果有1000张票,估计每次运行程序都会产生不同的结果,那是因为CPU会随机挑选线程去执行,不同线程都争着想要被CPU挑选上,所以可以利用同步锁,让他们排队,使线程有序的去被执行
      

  6.   

    发现运行结果每一次都不同。
    因为多个线程都获取cpu的执行权。cpu执行到谁,谁就运行。
    明确一点,在某一个时刻,只能有一个程序在运行。(多核除外)
    cpu在做着快速的切换,以达到看上去是同时运行的效果。
    我们可以形象把多线程的运行行为在互相抢夺cpu的执行权。
     
    多线程的一个特性:随机性。谁抢到谁执行,至于执行多长,cpu说的算。