public class TicketThread implements Runnable {
   private   int i = 5;
   //我的理解是它是多个线程来共享它,不存在拷贝,修改以后必须马上写回。
   public void run(){
      while(i>0){ 
         i = i+9999;
         i = i- 9999;
         i = i+9999;
         i = i- 9999;
         i = i+9999;
         i = i- 9999;
         i = i+9999;
         i = i- 9999;
         i = i+9999;
         i = i- 9999;
         i--;
         System.out.println("1:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
         System.out.println("2:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
         System.out.println("3:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
         System.out.println("4:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
         System.out.println("5:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
         try {
            Thread.sleep(1000);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }      
   }
   
   public static void main(String[] args) {
      TicketThread ticketThread = new TicketThread();
      
      Thread t1 = new Thread(ticketThread);
      Thread t2 = new Thread(ticketThread);
      Thread t3 = new Thread(ticketThread);
      Thread t4 = new Thread(ticketThread);
      Thread t5 = new Thread(ticketThread);
      Thread t6 = new Thread(ticketThread);
      Thread t7 = new Thread(ticketThread);
      Thread t8 = new Thread(ticketThread);
      
      t1.start();
      t2.start();
      t3.start();
      t4.start();
      t5.start();
      t6.start();
      t7.start();
      t8.start();
      
   }
}
1:Thread-0卖出车票,车票还剩 4 张
2:Thread-0卖出车票,车票还剩 3 张  //怎么会成了3张???
1:Thread-1卖出车票,车票还剩 3 张
2:Thread-1卖出车票,车票还剩 3 张
3:Thread-1卖出车票,车票还剩 3 张
4:Thread-1卖出车票,车票还剩 3 张
5:Thread-1卖出车票,车票还剩 3 张
1:Thread-2卖出车票,车票还剩 2 张
1:Thread-4卖出车票,车票还剩 1 张
2:Thread-4卖出车票,车票还剩 1 张
3:Thread-4卖出车票,车票还剩 1 张
4:Thread-4卖出车票,车票还剩 1 张
5:Thread-4卖出车票,车票还剩 0 张
3:Thread-0卖出车票,车票还剩 2 张
4:Thread-0卖出车票,车票还剩 0 张  //做为独立的线程,它内部存储的应该是3张,又不会再去读i一次。
5:Thread-0卖出车票,车票还剩 0 张
2:Thread-2卖出车票,车票还剩 1 张
1:Thread-3卖出车票,车票还剩 0 张
2:Thread-3卖出车票,车票还剩 0 张
3:Thread-3卖出车票,车票还剩 0 张
4:Thread-3卖出车票,车票还剩 0 张
5:Thread-3卖出车票,车票还剩 0 张
3:Thread-2卖出车票,车票还剩 0 张
4:Thread-2卖出车票,车票还剩 0 张
5:Thread-2卖出车票,车票还剩 0 张

解决方案 »

  1.   

    我发你一本书,Java Memory Model,你看不?
      

  2.   

    我想要解释,i设置成volatile对结果一点影响都没有。
      

  3.   

    Java Memory Model发我一本吧·[email protected]谢谢
      

  4.   

    发我一本吧, 谢谢
    [email protected]
      

  5.   

    在线程中把要做的操作下在一个方法中,向我这个样子
    public synchronized void make() {
     while(i>0){ 
             i = i+9999;
             i = i- 9999;
             i = i+9999;
             i = i- 9999;
             i = i+9999;
             i = i- 9999;
             i = i+9999;
             i = i- 9999;
             i = i+9999;
             i = i- 9999;
             i--;
             System.out.println("1:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
             System.out.println("2:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
             System.out.println("3:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
             System.out.println("4:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
             System.out.println("5:"+Thread.currentThread().getName()+"卖出车票,车票还剩 "+i+" 张");
             try {
                Thread.sleep(1000);
             } catch (InterruptedException e) {
                e.printStackTrace();
             }
    }然后在run中引用make方法就OK了。你在回去测试下。
      

  6.   

    volatile只是对一个变量保证原子操作,并不等于同步
      

  7.   

    i确实被多个线程共享啊,只有1个TicketThread实例,下边线程初始化那里如果改成
          Thread t1 = new Thread(new TestC());
          Thread t2 = new Thread(new TestC());
          Thread t3 = new Thread(new TestC());
    ...
    才是各线程管各线程的int i可以在i--之前再插入sleep效果,可以很容易观察到数据数据上锁不上锁的效果区分
      

  8.   

    如果实现runnable,那所有启动的线程都共享一份变量;如果继承thread,则每启动一个线程,每个线程都会有相对独立的变量。